John Carpenter John Carpenter - 2 months ago 9
C# Question

TryRemove a key-value pair from ConcurrentDictionary in C#

The scenario I have is I want a method on

ConcurrentDictionary
like this.

bool TryRemove(TKey key, TValue value) {
// remove the value IF the value passed in == dictionary[key]
// return false if the key is not in the dictionary, or the value is not equal
}


Is there a way to do this concurrently? I'm struggling to find an answer for this scenario, even though it seems like this is a common use case.

I could do something like this, but I want to avoid a lock if I'm already using a
ConcurrentDictionary
. I'd also have to have locks on
GetOrAdd()
or
AddOrUpdate()
calls elsewhere. It just seems like there should be a better way with a
ConcurrentDictionary
.

ConcurrentDictionary<int, string> dict = ...;

/// stuff

int keyTryToRemove = 1337;
string valTryToRemove = "someValue";

bool success = false;
lock(keyTryToRemove) {
string val;
if (dict.TryRemove(keyTryToRemove, out val)) {
if (val == valTryToRemove) {
success = true;
}
else { // reinsert value, UGLY!
dict[keyTryToRemove] = val;
success = false;
}
} else {
success = false;
}
}

Answer

Since ConcurrentDictionary<TKey, TValue> class implements (although explicitly) IDictionary<TKey, TValue>, thus ICollection<KeyValuePair<TKey, TValue>>, you can simply cast it to the later and use Remove method like this:

bool success = ((ICollection<KeyValuePair<TKey, TValue>>)dict).Remove(
    new KeyValuePair<TKey, TValue>(key, value));

The implementation internally uses the same thread safe method (passing additionally the value to be checked) as the public TryRemove method - exactly as it should be.

Comments