Represents a thread-safe collection of key/value pairs that can be accessed by multiple threads concurrently.
Creating an instance works pretty much the same way as with Dictionary<TKey, TValue>
, e.g.:
var dict = new ConcurrentDictionary<int, string>();
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 a value is the same as with the Dictionary<TKey,TValue>
:
string value = null;
bool success = dict.TryGetValue(1, out 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:
string theValue = dict.GetOrAdd(2, "Second");
Using a factory for adding a value, if value is not present:
string theValue2 = dict.GetOrAdd(2, (key) => key == 2 ? "Second" : "Not Second." );