【发布时间】:2015-10-13 07:37:19
【问题描述】:
当使用HashSet<string> 来检查之前是否处理过某个项目(即仅使用Add 和Contains)。此外,它不相关,当 Contains 返回 false 时,即使它是在之前添加的......
我遇到了以下没有锁定的异常:
[IndexOutOfRangeException: 索引超出了数组的范围。] System.Collections.Generic.HashSet`1.AddIfNotPresent(T值) +6108128
只锁定 Add 调用就足够了吗?
跟随似乎永远有效 - 但这不是证据......
HashSet<string> hashSet = new HashSet<string>();
Parallel.ForEach(GetString(), h =>
{
hashSet.Contains(h);
lock(hashSetLock)
{
hashSet.Add(h);
}
hashSet.Contains(h);
});
准确地说:我知道在没有锁的情况下调用Contains 不是线程安全的。我的问题是(接受误报)上述代码是否会引发异常或破坏底层数据结构(=HashSet)的内部状态。
【问题讨论】:
-
这是您的实际代码吗?因为它没有多大意义。
-
这只是一个重现它的测试......
-
这不是一个很好的例子。有很多方法可以以线程安全的方式生成此哈希集。如果你真的想从多个线程修改集合,你可以使用 ConcurrentDictionary
,它使用与 key 和 value 相同的值。