我正在尝试遍历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) ) );
如何将此参数传递给新的thead?
答案 0 :(得分:1)
您的方法存在一些问题:
首先,您创建委托的语法是错误的: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);
<强>第2部分强>
已经覆盖了代码中的问题,一般来说,如果正在执行的任务不是长时间运行的任务,那么建议考虑使用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);
}
}