Represents a thread-safe collection of key/value pairs that can be accessed by multiple threads concurrently.

Creating an instance

Creating an instance works pretty much the same way as with Dictionary<TKey, TValue>, e.g.:

var dict = new ConcurrentDictionary<int, string>();

Adding or Updating

You might be surprised, that there is no Add method, but instead there is AddOrUpdate with 2 overloads:

  1. AddOrUpdate(TKey key, TValue, Func<TKey, TValue, TValue> addValue) - Adds a key/value pair if the key does not already exist, or updates a key/value pair by using the specified function if the key already exists.
  2. AddOrUpdate(TKey key, Func<TKey, TValue> addValue, Func<TKey, TValue, TValue> updateValueFactory) - Uses the specified functions to add a key/value pair to the if the key does not already exist, or to update a key/value pair if the key already exists.

Adding or updating a value, no matter what was the value if it was already present for given key (1):

string addedValue = dict.AddOrUpdate(1, "First", (updateKey, valueOld) => "First");

Adding or updating a value, but now altering the value in update, based on the previous value (1):

string addedValue2 = dict.AddOrUpdate(1, "First", (updateKey, valueOld) => $"{valueOld} Updated");

Using the overload (2) we can also add new value using a factory:

string addedValue3 = dict.AddOrUpdate(1, (key) => key == 1 ? "First" : "Not First", (updateKey, valueOld) => $"{valueOld} Updated");

Getting value

Getting a value is the same as with the Dictionary<TKey,TValue>:

string value = null;
bool success = dict.TryGetValue(1, out value);

Getting or Adding a value

There are two mehod overloads, that will get or add a value in a thread-safe manner.

Get value with key 2, or add value “Second” if the key is not present: