Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safety considerations with IDictionary and ConcurrentDictionary

This question is primarily academic - I understand this is not necessarily practical code.

Consider this code, where thread-safety is a concern:

// In the constructor
IDictionary<string, string> myDictionary = new ConcurrentDictionary<string, string>();

...

// Elsewhere in the class
myDictionary.Add("foo", "bar");

My overall question: How is this handled from a concurrency point of view?

Would this be considered thread-safe, and if so, why? I ask because the (known) thread-safe method is AddOrUpdate - I don't have access to this with IDictionary. Is the CLR "smart enough" to know what's going on here? Is there a property of inheritance I am missing here, could the .Add call be mutated into an .AddOrUpdate call "under the hood"?

like image 652
Matt Avatar asked Sep 16 '25 15:09

Matt


1 Answers

CLR is not related here. ConcurrentDictionary implements interface IDictionary<TKey, TValue> implicitly, and you can see what it does for IDictionary.Add here:

void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
     if (!TryAdd(key, value))
     {
          throw new ArgumentException(GetResource("ConcurrentDictionary_KeyAlreadyExisted"));
    }
}

So it calls TryAdd ("safe" method of ConcurrentDictionary) and if unable to add key - throws exception that entry with such key already exists.

It's still "thread-safe", because you cannot have nasty side effects which you will using regular dictionary and adding items there from multiple threads. If you prepare for such exception - you can safely add items with Add to such dictionary from multiple threads.

like image 140
Evk Avatar answered Sep 18 '25 10:09

Evk