When a ConcurrentBag is better than a List?

感情迁移 提交于 2019-12-05 00:13:16

You have been lucky; Parallel.ForEach to populate a List is not thread-safe, you will eventually run into problems.

According to MSDN, List<T> is not thread safe:

Any instance members are not guaranteed to be thread safe.

A List<T> can support multiple readers concurrently, as long as the collection is not modified. Enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with one or more write accesses, the only way to ensure thread safety is to lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

ConcurrentBag is what you should use for this, which is thread-safe for multiple readers and writers.

If you're using Parallel.ForEach to populate a List<T> and everything is working just fine then you're simply getting lucky. The ForEach method can and will run your code on multiple threads so any communication outside the ForEach must be with objects that can handle concurrent updates. List<T> cannot but ConcurrentBag<T> can.

ConcurrentBag is the correct answer, only in .NET 4.0 it is very slow. This has been fixed in .NET 4.5. See http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

Both ConcurrentStack and ConcurrentQueue will also work in your situation...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!