我正在使用以下代码

var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
    processed.Add(SomeProcessingFunc(item));
});

上面的代码线程安全吗?处理过的列表是否有可能损坏?还是应该在添加之前使用锁?
var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
    lock(items.SyncRoot)
        processed.Add(SomeProcessingFunc(item));
});

谢谢。

最佳答案

不!这根本不安全,因为processed.Add并非如此。您可以执行以下操作:

items.AsParallel().Select(item => SomeProcessingFunc(item)).ToList();

请记住,Parallel.ForEach主要是针对序列中每个元素的命令式操作而创建的。您要做的是映射:投影序列的每个值。那就是创建Select的目的。 AsParallel以最有效的方式跨线程扩展它。

此代码正常工作:
var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
    lock(items.SyncRoot)
        processed.Add(SomeProcessingFunc(item));
});

但是在多线程方面毫无意义。每次迭代lock强制完全顺序执行,一堆线程将等待单个线程。

10-04 14:33