Summary of thread-safe collections in .NET
August 5, 2015 Leave a comment
The System.Collections.Concurrent namespace has 4 thread-safe collections that you can use in multi-threaded applications. The starting point is that you have a multi-threaded app where the same collection needs to be accessed by different threads. In that case the well-know collection types, like HashSet, List, Dictionary etc. simply won’t be enough.
If many different threads have access to the same resource then there’s no guarantee on the state of that resource in the moment a thread accesses it in some way: deletion, lookup, insertion or modification. Another thread may have accessed the same resource just milliseconds before that and the other thread will access the resource under the wrong assumptions. You’ll end up with buggy code with unpredictable results and ad-hoc fixes and patches that probably won’t solve the root of the problem.
So in case you need a shared collection the System.Collections.Concurrent namespace is a good starting point. Here’s a short summary of the thread-safe, i.e. concurrent collection types and some links with more explanation and code samples:
- ConcurrentStack: the thread safe equivalent of the standard last-in-first-out Stack collection
- ConcurrentQueue: the thread-safe equivalent of the standard first-in-first-out Queue collection
- ConcurrentBag: this is also a thread-safe collection but it has no matching one-to-one single-threaded implementation. It is an unordered collection meaning that there’s no pre-defined order in which the elements are retrieved from the bag. In practice a ConcurrentBag will work very similarly to a ConcurrentDictionary
- ConcurrentDictionary: the thread-safe equivalent of the standard key-value pair collection, i.e. the Dictionary. This is undoubtedly the most versatile concurrent collection of the 4. Although there’s no ConcurrentList or ConcurrentSet you can mimic a list or a set using a ConcurrentDictionary. Hence if you really need a thread-safe list then a quick solution is to employ a ConcurrentDictionary of key type integer and value of whatever type your objects are. The key can stand for the position of the element in the mimicked list
View the list of posts on the Task Parallel Library here.