问题
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?
}
回答1:
I think that you need to implement your own Dictionary
that somehow remembers which Task added which element.
Disclaimer
But I would recommend to remove what ever detail you have that leaded to this requirement since it sounds somewhat fishy to me that elements can only be removed by its creating workflow.
I say that because what if workflow 1
inserted the element elm1
and didn't removed it while it was working. So the element elm1
remains in the dictionary and nobody can remove it since its creating workflow has ended.
来源:https://stackoverflow.com/questions/58080607/how-to-implement-tryremove-conditional-to-concurrentdictionary