C#中的线程:如何保持循环索引线程安全?

时间:2016-07-11 13:59:44

标签: c# multithreading thread-safety

在下面的示例中,似乎for循环的索引i由每个线程独立修改,导致奇怪的i值(倍数,甚至大于{{1}的值在System.Environment.ProcessorCount-1

如何在C#中正确完成多线程循环?

DoWork_Threaded()

2 个答案:

答案 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();
}

这使我的机器输出合理。