ConcurrentBag比List好吗?

时间:2011-08-25 16:10:44

标签: .net parallel-processing parallel-collections

我正在使用Parallel.Foreach来填充外部ConcurrentBag。我也尝试使用一个普通的List,一切正常。

我很幸运或者我错过了ConcurrentBag的特殊范围?

3 个答案:

答案 0 :(得分:18)

你很幸运;填充List的Parallel.ForEach不是线程安全的,最终会遇到问题。

根据MSDN,List<T>不是线程安全的:

  

不保证所有实例成员都是线程安全的。

     

列表&lt; T&gt;可以同时支持多个读者,只要   集合未被修改。列举一个集合是   本质上不是一个线程安全的程序。在罕见的情况下   枚举与一个或多个写访问争用,唯一的方法   确保线程安全是在整个过程中锁定集合   列举。允许多个访问集合   阅读和写作的线程,你必须实现自己的   同步。

ConcurrentBag是您应该使用的,这对多个读者和作者来说是线程安全的。

答案 1 :(得分:5)

如果您正在使用Parallel.ForEach来填充List<T>并且一切正常,那么您只是运气好。 ForEach方法可以并且将在多个线程上运行您的代码,因此ForEach之外的任何通信必须与可以处理并发更新的对象一起。 List<T>不能ConcurrentBag<T>

答案 2 :(得分:2)

ConcurrentBag是正确答案,仅在.NET 4.0中它非常慢。这已在.NET 4.5中修复。见http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

ConcurrentStack和ConcurrentQueue也适用于您的情况......