When will ConcurrentDictionary TryRemove return false

C#.NetConcurrency

C# Problem Overview


Will it only return false if the dictionary does not contain a value for the given key or will it also return false due to thread race conditions, like another thread adds/updates something?

Question in code:

ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1); 

Edit: I think that it only will return false if it does not contain a value for the given key, but want to be absolutely sure.

C# Solutions


Solution 1 - C#

While Mitch is right that a ConcurrentDictionary is not vulnerable to race conditions, I think the answer to the question you are asking is that yes, if the key is present, TryRemove will work and will return true.

In the code you posted, there's no way that TryRemove would return false since cd is a local variable not accessed anywhere else. But if some code elsewhere were given a reference to this ConcurrentDictionary object and were removing keys on a separate thread, then it's possible that TryRemove could return false, even here -- but only because the key was already removed, not because some other action is being performed on the dictionary and the key is somehow "stuck" there.

Solution 2 - C#

The ConcurrentDictionary does not suffer from race conditions. That's why you use it.

> Return Value > > true if an object was removed > successfully; otherwise, false.

Solution 3 - C#

One other point to make:

> // This might fail if another thread is adding with key value of 1. > cd.TryAdd(1, "one");

This comment is incorrect and possibly suffers from the same misconception about what it means to 'try'. It's not about a concurrent attempt to add, it's whether a value has already been added with key 1.

Consider a standard Dictionary<TKey,TValue>. The equivalent code would be:

if (!d.Contains(1))
    d.Add(1, "one");

This requires two operations. There's no way to design such an API to be threadsafe, as cd might have a value with key 1 added between the call to Contains and Add, which would then result in Add throwing.

The concurrent collections have APIs that logically bundle these test-and-do pairs into single atomic operations, behind a single API.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin Ingvar Kofoed JensenView Question on Stackoverflow
Solution 1 - C#Dan TaoView Answer on Stackoverflow
Solution 2 - C#Mitch WheatView Answer on Stackoverflow
Solution 3 - C#Drew NoakesView Answer on Stackoverflow