通过XmlNodeList循环,然后为每个线程启动新线程
本文关键字:线程 启动 新线程 循环 XmlNodeList 然后 通过 | 更新日期: 2023-09-27 18:04:09
我正在尝试通过XmlNodeList循环,从中获取一些数据,然后启动一个使用此数据的新线程。
到目前为止我写的是:
public void startRun(string kwd)
{
doRun run = new doRun();
run.run(kwd);
}
private void startBtn_Click(object sender, EventArgs e)
{
XmlDocument searches = new XmlDocument();
searches.Load("data''Searches.xml");
XmlNodeList search = searches.SelectNodes("Searches/search");
var nodeCount = search.Count;
for(var i = 0; i < nodeCount; i++)
{
string kwd = System.Uri.EscapeDataString(search[i].SelectSingleNode("query").InnerText);
doRun run = new doRun(this);
Thread newThread = new Thread( new ThreadStart( startRun(kwd) ) );
}
}
这根本行不通。Visual Studio显示这一行的Method name expected
:
Thread newThread = new Thread( new ThreadStart( startRun(kwd) ) );
如何将这个参数传递到新的头部?
你的方法有几个问题:
首先,您创建委托的语法是错误的:new ThreadStart(startRun(kwd))
是无效的语法。正确的语法是:new ThreadStart(startRun)
—只使用方法名。
然后,如果你想传递一个参数给线程,你应该使用ParameterizedThreadStart委托而不是ThreadStart委托。
Thread newThread = new Thread( new ParameterizedThreadStart(startRun));
并通过调用Start(...)
来启动线程:
newThread.Start(kwd);
startRun
的签名应该在参数中使用对象而不是字符串:
public void startRun(object kwdObject)
内部可以将kwd
转换为string
来使用:
public void startRun(object kwdObject)
{
string kwd = (string)kwdObject;
// continue to do work..
现在,就startRun
的实现而言,该方法本身似乎是多余的。如果您有一个名为doRun
的类(顺便说一下,将类名的第一个字母大写是很好的做法)-那么为什么不直接使用doRun的run方法作为ThreadStart委托呢?除非doRun.run(..)不接受对象,在这种情况下,您创建转发函数的方法是可以的。
doRun run = new doRun();
run.run(kwd);
Part2
已经涵盖了代码中的问题,一般来说,如果你正在执行的任务不是长时间运行的任务(即,如果你期望任务在几秒钟内完成),建议考虑使用ThreadPool工作线程而不是手动创建一个新线程来执行你的任务。
要做到这一点,您可以这样修改代码: for(var i = 0; i < nodeCount; i++)
{
string kwd = System.Uri.EscapeDataString(search[i].SelectSingleNode("query").InnerText);
ThreadPool.QueUserWorkItem((WaitCallback)startRun, kwd);
}
第3部分
一个完整的例子,使用ThreadPool线程:
public void startRun(object kwd)
{
doRun run = new doRun();
run.run((string)kwd);
}
private void startBtn_Click(object sender, EventArgs e)
{
XmlDocument searches = new XmlDocument();
searches.Load("data''Searches.xml");
XmlNodeList search = searches.SelectNodes("Searches/search");
var nodeCount = search.Count;
for(var i = 0; i < nodeCount; i++)
{
string kwd = System.Uri.EscapeDataString(search[i].SelectSingleNode("query").InnerText);
ThreadPool.QueueUserWorkItem((WaitCallback)startRun, kwd);
// replace line above with the following two lines if you want to use regular threads
// Thread newThread = new Thread((ParameterizedThreadStart)startRun);
// newThread.Start(kwd);
}
}