Parallel.ForEach Misbehavior

TKh*_*ili 11 c# parallel-processing task-parallel-library

可能重复:
并行处理期间的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);
Run Code Online (Sandbox Code Playgroud)

这产生了一个输出:

平行计数:495939

顺序计数:500000

我运行了几次,并行循环似乎永远不会在适当的时间执行.任何人都能解释这种"不端行为"吗?并行循环是否值得信赖?

PS我知道在提供的代码示例中有很多废话,比如ToString()调用一个整数而不是解析它们但这只是我在测试时提出的随机代码.提前致谢.

the*_*yer 14

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

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

要允许多个线程访问集合以进行读写,您必须实现自己的同步.