将foreach循环更改为Parallel.ForEach和奇怪的错误

时间:2012-07-23 16:45:46

标签: c#

我使用传统语法

编写了几个循环
foreach(x in xs) {....}

这些循环中的一些在计算方面非常密集,我只是使用这样的并行语法来改变它们:

Parallel.ForEach(x, xs => {...});

我看到性能大幅提升!!现在我的问题是:我是否使用并行多线程引入错误?我读到线程安全性很复杂,可能会产生奇怪的错误;我应该关注什么?

2 个答案:

答案 0 :(得分:4)

访问共享状态很可能无法产生所需的结果。简单的例子:

int sum = 0;
for (int i = 0; i < 1000000; i++)
{
    sum++;
}

将此更改为

Parallel.For(0, 1000000, i => { sum++; });

并且您会看到sum会有一些随机值,因为多个线程正在读/写sum

如果您锁定更新,您将解决问题,但您实际上将再次将操作转换为顺序操作。

您需要确保循环中发生的任何事情都是安全的。

Microsoft模式和实践确实a book解释了所有这些以及更多内容。在更改代码以使用并行循环之前,应该检查它。

答案 1 :(得分:2)

明确地说 - 发布你的迭代/循环代码。

但通常情况下,您的迭代应该彼此独立并尝试避免共享状态。并行迭代资源中的任何共享资源都可能引入错误。

此外,当您的计算依赖于其他计算或并行操作或循环时,更好地使用TPL任务链,这也有助于避免共享的跨线程资源。

更多信息和样本和模式/反模式在免费的Microsoft书中得到了很好的描述:并行编程模式:使用.NET Framework 4理解和应用并行模式

在此下载

http://www.microsoft.com/en-us/download/details.aspx?id=19222