最近,我可以从多个线程更新DictionaryI had a need,显然,该工作的候选对象是内置的ConcurrentDictionary。不幸的是,由于致命的限制,我最终没有使用它,而是使用受Dictionary保护的普通lockTryRemove不提供允许有条件删除元素的重载。可用的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保留在词典中,并且自其创建工作流程结束以来,没有人可以删除它。

10-07 16:05