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

C#-使用Lambda创建多个线程,c#,multithreading,lambda,C#,Multithreading,Lambda,紧接着 Thread.Sleep(100); 我假设这是可行的,因为现在新创建的线程在创建下一个线程之前有一些时间进行初始化。但这是一个解决方案,不是修复方案。是因为lambda表达式的工作方式吗 如何正确地绕过此问题?问题在于在lambda中捕获I的方式。在循环内创建一个本地副本,使每个lambda捕获一个不同的值: t.Start(); public void gatherDatafromSwitchs(设备[]交换机){ List workerThreads=new List();

紧接着

Thread.Sleep(100); 
我假设这是可行的,因为现在新创建的线程在创建下一个线程之前有一些时间进行初始化。但这是一个解决方案,不是修复方案。是因为lambda表达式的工作方式吗


如何正确地绕过此问题?

问题在于在lambda中捕获
I
的方式。在循环内创建一个本地副本,使每个lambda捕获一个不同的值:

t.Start();
public void gatherDatafromSwitchs(设备[]交换机){
List workerThreads=new List();
for(int i=0;iGatherDataFromSwitch(开关[j]);
workerThreads.Add(t);
t、 Start();
}
foreach(workerThreads中的线程d)d.Join();//等待所有线程完成
}

注意将
i
复制到
j
。如果您使用了resharper,您的代码将产生警告,更多关于此问题的信息

这确实修复了它,我最初从foreach循环开始。复制对象以便将其传递给lambda似乎有些奇怪。@Maximilian Aelvoet:事实上,我更喜欢第二个版本,这使得您将索引作为参数传递给线程更加清楚。至少对我来说,这更清楚,因为我开始使用pthreads编程顺便说一句,不要忘了将答案标记为已接受,以防它解决了您的问题。只是解释一下:初始版本的问题在于lambda在实际执行时取值
i
。由于您启动的线程是异步运行的,因此无法知道当每个线程到达使用
i
的代码时
i
将具有什么值。因此,如果我做对了,值
i
只有在我调用
t.start()
时才会被lambda读取,但因为就在那之后,下一次迭代开始,
i
值被更改,因此我得到了奇怪的结果?如果是,谢谢你的解释!但是lambda只在线程启动后启动?
t.Start();
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
}
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
}
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 
}