MSDN上ConcurrentBag的描述不明确:
当订购无关紧要时,袋子对于存储物品很有用,而且与套装不同,袋子支持重复。 ConcurrentBag是一个线程安全的包实现,针对同一个线程生成和使用存储在包中的数据的情况进行了优化。
我的问题是线程安全,如果在Parallel.ForEach中使用ConcurrentBag是一个好习惯。
For Instance:
private List<XYZ> MyMethod(List<MyData> myData)
{
var data = new ConcurrentBag<XYZ>();
Parallel.ForEach(myData, item =>
{
// Some data manipulation
data.Add(new XYZ(/* constructor parameters */);
});
return data.ToList();
}
这样我就不必使用常规List在Parallel.ForEach中使用同步锁定。
非常感谢。
答案 0 :(得分:8)
这对我来说很好看。你使用它的方式是线程安全的。
如果您可以返回IEnumerable<XYZ>
,那么在完成后不复制到List<T>
可以提高效率。
答案 1 :(得分:0)
ConcurrentBag和Parallel.ForEach在我看来,没问题。如果在具有大量多用户访问权限的方案中使用此类型,则实现中的这些类可能会将cpu进程升级到可能导致Web服务器崩溃的级别。此外,这个实现启动N个任务(线程)来执行每个迭代,所以在选择这个类和实现时要小心。我最近在这种情况下花了我不得不提取内存转储来分析我的Web应用程序核心发生了什么。所以,要小心'因为Concurrentbag是ThreadSafe,而在Web场景中,这是没有更好的方法。