0

我正在尝试遍历 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 StudioMethod name expected对这一行说:

Thread newThread = new Thread( new ThreadStart( startRun(kwd) ) );

如何将此参数传递给新的主题?

4

1 回答 1

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(..) 不接受 oject 在这种情况下,您创建转发函数的方法是可以的。

doRun run = new doRun();
run.run(kwd);

第2部分

照原样解决代码中的问题后,如果您正在执行的任务不是长时间运行的任务(即,如果您期望几秒钟内完成的任务)。

为此,您可以像这样修改代码:

  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);
    }
}
于 2013-03-14T18:49:24.733 回答