Recently I had a need for a Dictionary
that I could update from multiple threads, and the obvious candidate for this job was the build-in ConcurrentDictionary
. Unfortunately I ended up not using it, and using instead a normal Dictionary
protected with a lock
, because of a fatal limitation: the TryRemove
does not offer an overload that allows the conditional removal of an element. The available TryRemove
method removes and returns the removed element, but in my case it was mandatory to remove the element only if it was inserted earlier by the same workflow. Removing an element from a different workflow (even for a fraction of a μsec) could have undesirable consequences that I would prefer not to have to resolve. So my question is: Is it possible to amend the existing ConcurrentDictionary
class with a thread-safe conditional TryRemove
extension method?
For reference here is my use case. The dictionary is populated safely using the AddOrUpdate
method:
var dict = new ConcurrentDictionary<string, CancellationTokenSource>();
var cts = dict.AddOrUpdate("Key1", key => new CancellationTokenSource(),
(key, existingValue) =>
{
existingValue.Cancel();
return new CancellationTokenSource();
});
Later I would like to remove the value I inserted earlier by calling the non-existent method below:
var removed = dict.TryRemove("Key1", (key, existingValue) =>
{
return existingValue == cts;
});
This is the signature of the needed method:
public static bool TryRemove<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> source, TKey key,
Func<TKey, TValue, bool> predicate)
{
// Is it possible?
}