平行,为每一个不当行为



可能的重复
:并行处理期间的 C# 值存储

我今天在我的控制台应用程序中运行了一些性能测试,我偶然发现了一些非常出乎意料的事情。我的代码:

int iterations = 1000000;
var mainList = new List<string>();
for (int i = 0; i < iterations; i++)
{
mainList.Add(i.ToString());
}
var listA = new List<string>();
Parallel.ForEach(mainList, (listItem) =>
{
if (Int32.Parse(listItem)%2 == 0)
{
listA.Add(listItem);
}
});
Console.WriteLine("Parallel Count: {0}", listA.Count);
var listB = new List<string>();
foreach (var listItem in mainList)
{
if (Int32.Parse(listItem) % 2 == 0)
{
listB.Add(listItem);
}
}
Console.WriteLine("Sequential Count: {0}", listB.Count);

这导致了一个输出:

并行计数:495939

顺序计数:500000

我运行了几次,并行循环似乎从未在适当的次数上执行过。谁能解释这种"不当行为"?并行循环是否可信?

附言我知道在提供的代码示例中有很多废话,例如 ToString() 调用整数并解析它们,但这只是我在测试时想出的随机代码。提前谢谢。

你的问题不在于Parallel.ForEach。 您的问题出在List<int>- 该类不是线程安全的。 我的猜测是您在列表对象中遇到了线程安全问题。 尝试改用ConcurrentBag<int>,问题可能会消失。

来自关于List<T>线程安全性的Microsoft:

若要允许多个线程访问集合以进行读取和写入,必须实现自己的同步。

最新更新