3
public void GatherDataFromSwitches(Device[] switches)
{
    List<Thread> workerThreads = new List<Thread>();
    for(int i = 0; i < switches.Length - 1; i++)
    {
        Thread t = new Thread(unused => GatherDataFromSwitch(switches[i]));
        workerThreads.Add(t);
        t.Start();
    }
    foreach (Thread d in workerThreads) d.Join(); //wait for all threads to finish
}

如果我在运行该方法后循环通过交换机,我会注意到有些交换机没有添加数据,而有些交换机从多个交换机添加了数据。所以将引用传递给工作线程时出了点问题。我仍然不确定到底是什么,但我通过添加解决了这个问题

Thread.Sleep(100); 

紧接着

t.Start();

我假设这是可行的,因为现在新创建的线程在创建下一个线程之前有一些时间进行初始化。但这是一种解决方法,而不是修复方法。是因为 lambda 表达式的工作原理吗?

我该如何正确解决这个问题?

4

2 回答 2

3

问题是i在 lambda 中捕获的方式。在循环内制作一个本地副本,让每个 lambda 捕获一个不同的值:

public void GatherDataFromSwitches(Device[] switches)
{      
    List<Thread> workerThreads = new List<Thread>();
    for(int i = 0; i < switches.Length ; i++)
    {
        int j = i; // local i
        Thread t = new Thread(unused => GatherDataFromSwitch(switches[j]));
        workerThreads.Add(t);
        t.Start();
    }
    foreach (Thread d in workerThreads) d.Join(); //wait for all threads to finish
}

或者i显式地作为参数传递给线程:

public void GatherDataFromSwitches(Device[] switches)
{      
    List<Thread> workerThreads = new List<Thread>();
    for(int i = 0; i < switches.Length ; i++)
    {
        Thread t = new Thread(param => { j = (int)param; GatherDataFromSwitch(switches[j]); });
        workerThreads.Add(t);
        t.Start(i);
    }
    foreach (Thread d in workerThreads) d.Join(); //wait for all threads to finish
}
于 2012-06-07T09:39:59.847 回答
0
public void GatherDataFromSwitches(Device[] switches) {
     List<Thread> workerThreads = new List<Thread>();
     for(int i = 0; i < switches.Length ; i++)
     {
         int j = i;
         Thread t = new Thread(unused => GatherDataFromSwitch(switches[j]));
         workerThreads.Add(t);
         t.Start();
     }
     foreach (Thread d in workerThreads) d.Join(); //wait for all threads to finish 
}

i注意to的复制j。如果你有 resharper,你的代码会产生警告,更多关于这个问题的Access to Modified Closure

于 2012-06-07T09:41:00.747 回答