循环遍历XmlNodeList,然后为每个启动新线程

时间:2013-03-14 18:47:07

标签: c#

我正在尝试遍历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?

1 个答案:

答案 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);
    }
}