通过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) ) );

如何将这个参数传递到新的头部?

通过XmlNodeList循环,然后为每个线程启动新线程

你的方法有几个问题:

首先,您创建委托的语法是错误的: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);
    }
}