C# - 使用Lambda创建多个线程

时间:2012-06-07 09:37:15

标签: c# multithreading lambda

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表达式如何工作?

我如何妥善解决这个问题?

2 个答案:

答案 0 :(得分:3)

问题是在lambda中捕获i的方式。在循环中创建一个本地副本,让每个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
}

答案 1 :(得分: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复制到j。如果你有resharper,你的代码会产生警告,更多关于这个问题Access to Modified Closure