从ConcurrentDictionary安全删除列表映射

问题描述 投票:2回答:2

我有一个ConcurrentDictionary,它将简单类型映射到列表:

var dict = new ConcurrentDictionary<string, List<string>>();

当添加第一个值时,我可以使用AddOrUpdate()满足列表的初始化,以及将后续值添加到列表中。

但是,删除操作并非如此。如果我做类似的事情:

public void Remove(string key, string value)
{
    List<string> list;
    var found = dict.TryGetValue(key, out list);

    if (found)
    {
        list.Remove(value);
        if (list.Count == 0)
        {
            // warning: possible race condition here
            dict.TryRemove(key, out list);
        }
    }
}

...我的目的是如果对应列表不再具有任何值,则完全删除密钥(类似于概念上的引用计数),那么我冒着竞争的风险,因为有人可能会在我检查是否为空后立即将其添加到列表中

尽管在此简单示例中使用的是列表,但在这种情况下,我通常会有一个ConcurrentBag或ConcurrentDictionary,并且风险非常相似。

当相应的集合为空时,有什么方法可以安全地删除密钥,而无需借助锁?

c# concurrency race-condition concurrentdictionary
2个回答
2
投票

您的ConcurrentDictionary受保护,但您的列表不受保护。如果可以从多个线程访问列表(我假设是这种情况),则需要对列表的所有访问使用锁定,或者需要使用其他构造。


0
投票

我最近研究了同一主题,并在the newer version of this question中找到了更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.