gpt4 book ai didi

c# - 如何将新元素添加到作为 ConcurrentDictionary 值的哈希集中?

转载 作者:行者123 更新时间:2023-11-30 20:28:39 24 4
gpt4 key购买 nike

我有一个 ConcurrentDictionary,它的键是 long,值是 int 哈希集。我希望如果键不在字典中,则添加一个包含第一个元素的新哈希集。如果键存在,则将新元素添加到现有字典中。

我正在尝试这样的事情:

ConcurrentDictionary<long, HashSet<int>> myDic = new ConcurrentDictionary<long, HashSet<int>>();
int myElement = 1;
myDic.AddOrUpdate(1, new Hashset<int>(){myFirstElement},
(key, actualValue) => actualValue.Add(myElement));

此代码的问题在于第三个参数,因为 .Add() 方法返回一个 bool 值,而 AddOrUpdate 需要一个哈希集。第一和第二个参数是对的。

所以我的问题是如何以线程安全的方式向散列集添加新元素并避免重复(这就是我使用散列集作为值的原因)。哈希集的问题是它不是线程安全的,如果我先获取它然后再添加新元素,那么我在字典之外进行操作,我可能会遇到问题。

谢谢。

最佳答案

要修复编译器错误,您可以这样做:

myDic.AddOrUpdate(1, new HashSet<int>() { myFirstElement },
(key, actualValue) => {
actualValue.Add(myFirstElement);
return actualValue;
});

但是 这不是线程安全的,因为“更新”函数不在任何锁内运行,因此您可能从多个线程添加到非线程安全的 HashSet .这可能会导致(例如)丢失值(例如,您向 HashSet 添加了 1000 个项目,但最终您只有 970 个项目)。 AddOrUpdate 中的更新函数不应该有任何副作用,这里有。

您可以将自己锁定在向 HashSet 添加值:

myDic.AddOrUpdate(1, new HashSet<int>() { myFirstElement },
(key, actualValue) => {
lock (actualValue) {
actualValue.Add(myFirstElement);
return actualValue;
}
});

但接下来的问题是您为什么首先使用无锁结构 (ConcurrentDictionary)。除此之外 - 任何其他代码都可能从您的字典中获取 HashSet 并在没有任何锁定的情况下在那里添加值,从而使整个事情变得无用。因此,如果您出于某种原因决定采用这种方式 - 您必须确保在从该字典访问 HashSet 时锁定所有代码。

而不是所有这些 - 只需使用并发集合而不是 HashSet。据我所知,没有 ConcurrentHashSet,但您可以使用另一个带有虚拟键的 ConcurrentDictionary 作为替代(或在互联网上查看自定义实现)。

旁注。这里

myDic.AddOrUpdate(1, new Hashset<int>(){myFirstElement}, 

每次调用 AddOrUpdate 时,您都会创建新的 HashSet,即使不需要该字典,因为键已经存在。而是使用带有附加值工厂的重载:

myDic.AddOrUpdate(1, (key) => new HashSet<int>() { myFirstElement },

编辑:ConcurrentDictionary 作为哈希集的示例用法:

var myDic = new ConcurrentDictionary<long, ConcurrentDictionary<int, byte>>();
long key = 1;
int element = 1;
var hashSet = myDic.AddOrUpdate(key,
_ => new ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(element, 0)}),
(_, oldValue) => {
oldValue.TryAdd(element, 0);
return oldValue;
});

关于c# - 如何将新元素添加到作为 ConcurrentDictionary 值的哈希集中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47033031/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com