Which members of .NET's ConcurrentDictionary are thread-safe? Which members of .NET's ConcurrentDictionary are thread-safe? multithreading multithreading

Which members of .NET's ConcurrentDictionary are thread-safe?


Notice the section of the documentation that covers explicit interface implementations. E.g. the class implements IDictionary.Add. This method is not a public or protected member of the class, but may be accessed via the IDictionary interface. It is these such members that are not being guaranteed to be thread safe.


Due to Explicit vs Implicit interface implementation.

If you take a look at the source code for ConcurrentDictionary<TKey, TValue> you may see that there are some methods that explicitly implement an interface (like object IDictionary.this[object key]) which although internally call the thread-safe version of the same operation this behavior may change in the future.

Think of it as division of responsibility:If I (as a class) receive an instance of ConcurrentDictionary<TKey, TValue> I know that it's that instance's responsibility to perform operations in a thread-safe manner.

However, if I (again as a class) receive an instance of IDictionary<TKey, TValue> then I should be aware if there should or shouldn't be a thread-safety concern. If there is no such concern I just use the dictionary as it is but if thread-safety is required it's my responsibility to perform all operations in a thread-safe manner.


There is a specific section in the documentation that makes clear not everything is thread-safe in the ConcurrentDictionary<TKey, TValue>:

All these operations are atomic and are thread-safe with regards to all other operations on the ConcurrentDictionary<TKey, TValue> class. The only exceptions are the methods that accept a delegate, that is, AddOrUpdate and GetOrAdd. For modifications and write operations to the dictionary, ConcurrentDictionary<TKey, TValue> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, delegates for these methods are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, the code executed by these delegates is not subject to the atomicity of the operation.

So there are some general exclusions and some situations specific to ConcurrentDictionary<TKey, TValue>:

  • The delegates on AddOrUpdate and GetOrAdd are not called in a thread-safe matter.
  • Methods or properties called on an explicit interface implementation are not guaranteed to be thread-safe;
  • Extension methods called on the class are not guaranteed to be thread-safe;
  • All other operations on public members of the class are thread-safe.