字典中的空键条目

Null key entry in a dictionary

我遇到了麻烦。

我有一本字典,其中包含一个空键条目...

这在我的 iis 应用程序中时常发生,然后在对该字典执行查找时冻结(100% cpu,无限循环):

FindEntry 方法的来源(未编译或reference sources)非常清楚:

1) 字典中不可能有空键

2) 鉴于我的字典私有字段,无限循环非常明显:

我有什么想法吗?

ps:我没有安装任何有趣的东西,比如 ryujit 或自定义 .net 构建。 只是 .Net 4.5

下的常规 iisexpress 运行

编辑

根据要求(我应该精确):我也没有对这本词典做任何有趣的事情。 只有一种用法:

  if (!readers.TryGetValue(type, out ret))
       readers[type] = ret = GetReaderOfTMethod.MakeGenericMethod(type).Invoke(this,null);

如果这个字典不限于单个线程(在一个方法中创建并在那里使用,但静态存储)那么我希望这会发生。

Dictionary 与任何其他代码一样,是在假设之前可能发生的情况下编写的。这些假设不考虑同时调用,例如假定如果字典正在调整大小,则在调整大小完成之前不会再次调整大小,一次只会尝试设置给定值,依此类推。

不要提防这一点,两次调用会使字典进入其编码人员未考虑的状态,然后可能会发生没有意义的事情,例如即使有空键也有空键不允许。

如果这种同时使用不会很普遍(而且看起来不会),那么用锁保护每次访问:

lock(lockObj)
  if (!readers.TryGetValue(type, out ret))
    readers[type] = ret = GetReaderOfTMethod.MakeGenericMethod(type).Invoke(this,null);

其中 lockObj 是与 readers 处于同一作用域的对象,用于锁定对其的所有访问。 (可能 readers 在这里作为锁定对象本身会很好地工作,但是当它是和不是一个好主意本身就是另一个话题)。

如果 reader 有任何其他用途,它们也应该使用相同的锁定对象锁定。

如果这种同时使用变得普遍,那么设计用于容忍这种使用的并发字典会更好(ConcurrentDictionary 在框架中,或者我的 ThreadsafeDictionary 都可以)。这些通常效率较低,但在一定水平的并发使用时效率更高。