6

好吧,所以我遇到了一个奇怪的小问题,坦率地说我没有想法。我想把它扔出去,看看我是否遗漏了我做错的事情,或者 ConcurrentDictionary 是否工作不正常。这是代码:

(Cache 是一个包含静态 ConcurrentDictionary Keys 的类)

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字典的东西,而且它永远不会运行,那怎么可能tmpnull


包括 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>();
}
4

2 回答 2

3

tmp如果您得到的不是从context.GetKeys(key). 在这种情况下,将为指定的键keys.Count() != 1插入一个空项(并从 中返回,并分配给)。 Cache.KeysGetOrAddtmp

编辑:只是想到了另一种可能性。什么数据类型是关键?它是某种自定义类吗?看起来是这样。如果是这样,您是否已Equals正确实施GetHashcode

于 2012-01-05T22:14:17.117 回答
1

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

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

于 2013-12-09T19:16:29.597 回答