我正在使用以下代码
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
强制完全顺序执行,一堆线程将等待单个线程。