sta*_*ser 29 c# list parallel-extensions task-parallel-library c#-4.0
我使用以下代码
var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
processed.Add(SomeProcessingFunc(item));
});
Run Code Online (Sandbox Code Playgroud)
上面的代码线程是否安全?处理后的列表是否有可能被破坏?或者我应该在添加之前使用锁?
var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
lock(items.SyncRoot)
processed.Add(SomeProcessingFunc(item));
});
Run Code Online (Sandbox Code Playgroud)
谢谢.
And*_*rey 30
没有!它根本不安全,因为processed.Add不是.你可以这样做:
items.AsParallel().Select(item => SomeProcessingFunc(item)).ToList();
Run Code Online (Sandbox Code Playgroud)
请记住,这Parallel.ForEach主要是为序列的每个元素的命令式操作创建的.你要做的是map:项目序列的每个值.这就是Select创造的目标.AsParallel以最有效的方式跨线程缩放它.
此代码正常工作:
var processed = new List<Guid>();
Parallel.ForEach(items, item =>
{
lock(items.SyncRoot)
processed.Add(SomeProcessingFunc(item));
});
Run Code Online (Sandbox Code Playgroud)
但就多线程而言毫无意义.lock在每次迭代时强制完全顺序执行,一堆线程将等待单线程.
来自 Jon Skeet 的书《C# in Depth》:
作为 .Net 4 中并行扩展的一部分,新命名空间中有几个新集合
System.Collections.Concurrent。这些被设计为在面对来自多个线程的并发操作时是安全的,并且锁定相对较少。
这些包括:
IProducerConsumerCollection<T>BlockingCollection<T>ConcurrentBag<T>ConcurrentQueue<T>ConcurrentStack<T>ConcurrentDictionary<TKey, TValue>| 归档时间: |
|
| 查看次数: |
12941 次 |
| 最近记录: |