我正在使用Parallel.Foreach来填充外部ConcurrentBag。我也尝试使用一个普通的List,一切正常。
我很幸运或者我错过了ConcurrentBag的特殊范围?
答案 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也适用于您的情况......