Ddd
Ddd

Reputation: 185

Why ConcurrentDictionary TryUpdate() method requires indicating oldValue?

When calling TryUpdate you should specify old value besides key, why is it required ? And additional question why TryUpdate method (and others similar) have while(true) loop wrapper inside ?

Upvotes: 5

Views: 4199

Answers (1)

Theodor Zoulias
Theodor Zoulias

Reputation: 43545

The ConcurrentDictionary<TKey,TValue> collection is designed to support concurrent scenarios, where operations must be atomic. For example let's say that you have a dictionary with string keys and int values, and you want to increment the value of the key "A". The following code is not atomic:

dictionary["A"]++;

Between reading the value and updating it, it is possible that another thread will change the value, resulting in the other thread's change being lost. It is easier to see it if we rewrite the above code like this:

int value = dictionary["A"];
value++;
dictionary["A"] = value;

The solution is to avoid updating the dictionary using the indexer, and use the TryUpdate instead. In case another thread intercepts our update, we'll have to start all over again, until we finally win the race at updating this key:

while (true)
{
    int existing = dictionary["A"];
    int updated = existing + 1;
    if (dictionary.TryUpdate("A", updated, existing)) break;
}

Doing loops with while (true), also known as "spinning", is a typical technique in low-lock multithreaded programming.

Related question: Is there a way to use ConcurrentDictionary.TryUpdate with a lambda expression?

Upvotes: 6

Related Questions