【发布时间】:2012-01-05 22:06:32
【问题描述】:
好的,所以我遇到了一个奇怪的小问题,坦率地说我没有想法。我想把它扔出去,看看我是否遗漏了我做错的事情,或者 ConcurrentDictionary 是否工作不正常。代码如下:
(缓存是一个包含静态 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;
问题是偶尔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>();
}
【问题讨论】:
-
也许字典中已经有一个
null值? -
有多少线程在运行这段代码?它似乎不是线程安全的。
-
@IlyaKogan - 不,字典在启动时是空的,并且从不包含空值,即使
if (tmp == null)内的断点被命中。 -
@oleksii 我的所有意图都是让它成为线程安全的。您能否具体说明您认为会导致问题的区域?
-
你确定这条线永远不会被击中吗?断点是在 lambda 中显式设置的,而不是在语句本身上?
标签: c# multithreading concurrency concurrentdictionary