c# - 如何实现以 ConcurrentDictionary 为条件的 TryRemove?

标签 c# .net concurrency concurrentdictionary

<分区>

最近I had a need对于我可以从多个线程更新的 Dictionary,这项工作的明显候选者是内置 ConcurrentDictionary .不幸的是,我最终没有使用它,而是使用了一个普通的 Dictionary 保护 lock,因为一个致命的限制:TryRemove不提供允许有条件地删除元素的重载。可用的 TryRemove 方法删除并返回删除的元素,但在我的例子中,只有在同一工作流之前插入元素时才必须删除该元素。从不同的工作流中删除一个元素(即使是几分之一微秒)可能会产生不良后果,我宁愿不必解决。所以我的问题是:是否可以使用线程安全的条件 TryRemove 扩展方法修改现有的 ConcurrentDictionary 类?

这里是我的用例供引用。使用 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 保留在字典中并且没有人可以删除它,因为它的创建工作流已经结束。

关于c# - 如何实现以 ConcurrentDictionary 为条件的 TryRemove?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58080607/

相关文章:

c# - Unity-Mono 在检查目录权限时抛出 PlatformNotSupportedException

android - 如何指定从 Android 模拟器调用 Web 服务的 URL?

concurrency - 为什么函数会提前返回?

go - 追加不是线程安全的?

c++ - 为什么 pthread_key_create 析构函数被调用了几次?

c# - 如何使用 Youtube API 检查视频观看是否受到限制?

c# - 使用 JSON.NET 将自定义名称添加到数组

c# - 我应该如何使用手动 DAL 处理复合实体的创建?

c# - 每次在进程中调用 XmlConfigurator.Configure() 时,log4net 如何不清除日志

c# - 面试代码示例