ConcurrentDictionary-字典损坏或代码错误
本文关键字:代码 错误 损坏 字典 ConcurrentDictionary- | 更新日期: 2023-09-27 18:19:38
好吧,所以我遇到了一个奇怪的小问题,坦率地说,我没有主意了。我想把它扔出去,看看我是否遗漏了我做错的事情,或者ConcurrentDictionary是否工作不正常。这是代码:
(Cache是一个包含静态ConcurrentDictionary密钥的类)
var tmp = Cache.Keys.GetOrAdd(type,
key =>
{
var keys = context.GetKeys(key);
if (keys.Count() == 1)
{
return new KeyInfo
{
Name = keys.First().Name,
Info = key.GetInfo(keys.First().Name)
};
}
return null;
});
if (tmp == null)
Cache.Keys.TryRemove(type, out tmp);
return tmp;
问题是偶尔tmp
是null
,导致TryRemove
行运行,但上面的return null;
行从未命中。既然return null
是唯一将null
放入字典的东西,而且它从未运行过,那么tmp
怎么可能是null
呢?
包括Cache类(此代码不使用SetNames):
public class Cache
{
public static ConcurrentDictionary<Type, Info> Keys = new ConcurrentDictionary<Type, Info>();
public static ConcurrentDictionary<Type, string> SetNames = new ConcurrentDictionary<Type, string>();
}
tmp
可以为空,如果您从context.GetKeys(key)
中获得除单个项之外的任何内容。在这种情况下,keys.Count() != 1
和一个空项将被插入到指定密钥的Cache.Keys
中(并从GetOrAdd
返回,并分配给tmp
)。
编辑:只是想到了另一种可能性。关键是什么数据类型?这是某种定制课程吗?看起来是的。如果是,您是否正确地实现了Equals
和GetHashcode
?
我应该在不久前关闭它,但我完全忘记了它。由于TryRemove
的原因,该示例不是线程安全的,但添加它只是为了调试目的。我最终通过重写它来解决这个问题,所以也许关于代码过时的一些评论是正确的。但是,该代码已不存在以进行确认。
我将此归因于用户错误(当然是我自己的错误)。感谢大家抽出时间!