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;

问题是偶尔tmpnull,导致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>();
}

ConcurrentDictionary-字典损坏或代码错误

tmp可以为空,如果您从context.GetKeys(key)中获得除单个项之外的任何内容。在这种情况下,keys.Count() != 1和一个空项将被插入到指定密钥的Cache.Keys中(并从GetOrAdd返回,并分配给tmp)。

编辑:只是想到了另一种可能性。关键是什么数据类型?这是某种定制课程吗?看起来是的。如果是,您是否正确地实现了EqualsGetHashcode

我应该在不久前关闭它,但我完全忘记了它。由于TryRemove的原因,该示例不是线程安全的,但添加它只是为了调试目的。我最终通过重写它来解决这个问题,所以也许关于代码过时的一些评论是正确的。但是,该代码已不存在以进行确认。

我将此归因于用户错误(当然是我自己的错误)。感谢大家抽出时间!