C# 如何实现TryRemove条件到ConcurrentDictionary?

C# 如何实现TryRemove条件到ConcurrentDictionary?,c#,.net,concurrency,concurrentdictionary,C#,.net,Concurrency,Concurrentdictionary,最近,我可以从多个线程更新一个字典,很明显,这个工作的候选者是内置的。不幸的是,我最终没有使用它,而是使用了一个受锁保护的普通字典,因为有一个致命的限制:不提供允许有条件删除元素的重载。可用的TryRemove方法删除并返回已删除的元素,但在我的情况下,只有在同一工作流先前插入该元素时,才必须删除该元素。从一个不同的工作流中删除一个元素(哪怕只有一点点微秒)可能会产生我不想解决的不良后果。因此,我的问题是:是否可以使用线程安全的条件TryRemove扩展方法修改现有的concurrentdire

最近,我可以从多个线程更新一个
字典
,很明显,这个工作的候选者是内置的。不幸的是,我最终没有使用它,而是使用了一个受
锁保护的普通
字典
,因为有一个致命的限制:不提供允许有条件删除元素的重载。可用的
TryRemove
方法删除并返回已删除的元素,但在我的情况下,只有在同一工作流先前插入该元素时,才必须删除该元素。从一个不同的工作流中删除一个元素(哪怕只有一点点微秒)可能会产生我不想解决的不良后果。因此,我的问题是:是否可以使用线程安全的条件
TryRemove
扩展方法修改现有的
concurrentdirectionary

这里是我的用例供参考。使用以下方法安全地填充词典:

这是所需方法的签名:

public static bool TryRemove<TKey, TValue>(
    this ConcurrentDictionary<TKey, TValue> source, TKey key,
    Func<TKey, TValue, bool> predicate)
{
    // Is it possible?
}
公共静态bool TryRemove(
此ConcurrentDictionary源TKey,
Func谓词)
{
//可能吗?
}

我认为您需要实现自己的
字典
,以某种方式记住哪个任务添加了哪个元素

免责声明 但我建议您删除导致此要求的任何细节,因为我觉得只有通过创建工作流才能删除元素有些可疑


我之所以这么说,是因为what-if
workflow 1
插入了元素
elm1
,并且在它工作时没有删除它。因此元素
elm1
仍保留在字典中,由于其创建工作流已结束,因此没有人可以删除它。

我认为这是不可能的。我能想到的唯一一件事是将
concurrentdirectionary
包装到一个类中,该类使用锁使方法线程安全……这就违背了这一点。@timpohmann我对此也持悲观态度。即使您建议使用包装类,也不仅需要
TryRemove
,而且需要包装的所有方法在相同的
lock
下操作,这完全违背了类的目的。例如“在我的情况下,只有在同一工作流较早插入元素时,才必须删除该元素”你的意思是只有插入元素的线程才可以删除它,但是任何线程都可以访问该元素吗?@Ackdari实际上在我的例子中,我在
async
方法中,在
wait
之前和之后。这就是为什么我谈论“工作流”而不是线程,因为相同的工作流稍后会在不同的线程中运行。要回答您的问题,所有工作流都可以更新任何元素(用不同的元素替换),但只有创建该元素的工作流才允许在不替换的情况下删除该元素。实际上,孤立元素(如果可能成为孤立元素,这很不可能)仍然可以删除。另一个工作流可以先替换元素,然后删除替换项。@TheodorZoulias,但谁可以删除元素的问题仍然存在。只有条目的原始创建者才能将其删除,或者只有最后替换元素的工作流才能将其删除,或者每个替换元素的工作流都可以将其删除?。替换元素具有将其从字典中删除的效果。允许工作流通过在原子操作(使用
AddOrUpdate
)中将“外来”元素替换为自己的元素来删除它。但不允许在不更换的情况下移除异物。这一要求听起来可能有些奇怪,但实际上是相当合理的,如果你深入研究我案件的细节,我想你会同意的。如果你感兴趣,它是。
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?
}