在下面的示例中,似乎for循环的索引i
由每个线程独立修改,导致奇怪的i
值(倍数,甚至大于{{1}的值在System.Environment.ProcessorCount-1
如何在C#中正确完成多线程循环?
DoWork_Threaded()
答案 0 :(得分:5)
首先,为什么不使用任务并行库而不是滚动自己的线程调度服务?它已经具有确定调度线程的处理器数量的逻辑。
要回答您的实际问题,您关闭循环变量。请参阅我的文章,了解为什么这是错误的:
https://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/
简而言之:i
是变量,变量更改。当lambda执行时,它将使用当前值i
执行,而不是创建委托时的值。
答案 1 :(得分:3)
将局部变量与匿名方法和线程一起使用可能会非常棘手。您需要复制匿名方法在更改时使用的值:
for (int i = 0; i < System.Environment.ProcessorCount; i++)
{
int a = i;
threads[i] = new Thread(() => DoWork_Threaded(a));
threads[i].Start();
}
这使我的机器输出合理。