最近,我可以从多个线程更新Dictionary
的I had a need,显然,该工作的候选对象是内置的ConcurrentDictionary
。不幸的是,由于致命的限制,我最终没有使用它,而是使用受Dictionary
保护的普通lock
:TryRemove
不提供允许有条件删除元素的重载。可用的TryRemove
方法将删除并返回已删除的元素,但是在我的情况下,仅当该元素是由同一工作流程较早插入时才必须删除的元素。从不同的工作流程中删除元素(即使仅需几微秒的时间),可能会产生不良后果,而我不希望解决。所以我的问题是:是否可以使用线程安全的条件ConcurrentDictionary
扩展方法来修改现有的TryRemove
类?
供参考,这是我的用例。使用AddOrUpdate
方法安全地填充字典:
var dict = new ConcurrentDictionary<string, CancellationTokenSource>();
var cts = dict.AddOrUpdate("Key1", key => new CancellationTokenSource(),
(key, existingValue) =>
{
existingValue.Cancel();
return new CancellationTokenSource();
});
稍后,我想通过调用以下不存在的方法来删除我先前插入的值:
var removed = dict.TryRemove("Key1", (key, existingValue) =>
{
return existingValue == cts;
});
这是所需方法的签名:
public static bool TryRemove<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> source, TKey key,
Func<TKey, TValue, bool> predicate)
{
// Is it possible?
}
最佳答案
我认为您需要实现自己的Dictionary
,以某种方式记住哪个Task添加了哪个元素。
免责声明
但是我建议您删除导致此要求的所有细节,因为在我看来,只有通过其创建工作流程才能删除元素,这听起来有些可疑。
我说这是因为,如果workflow 1
插入元素elm1
并在工作时没有将其删除的话,该怎么办。因此,元素elm1
保留在词典中,并且自其创建工作流程结束以来,没有人可以删除它。