字典中的空键输入

时间:2015-02-05 23:59:19

标签: c# .net

我面临着一个令人不安的情况。

我有一个包含空键条目的词典......

null key in dictionary

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

enter image description here

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

1)词典中没有空键

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

private fields

任何想法发生在我身上?

ps:我没有像ryujit或custom .net build那样安装任何有趣的东西。 只是在.Net 4.5下运行的常规iisexpress

修改

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

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

1 个答案:

答案 0 :(得分:3)

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

Dictionary与任何其他代码一样,编写了关于之前可能发生的事情的假设。这些假设不考虑同时呼叫,例如假设如果调整字典大小,调整大小不会再次发生,直到完成调整大小,一次只能进行一次尝试来设置给定值,依此类推。

不要防范这种情况,并且两个调用可以将字典置于其编码器未考虑的状态,然后可能发生无意义的事情,就像有一个空键,即使空键不是'允许。

如果这种同时使用不常见(而且似乎不会),那么用锁来保护每次访问:

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

其中lockObj是与readers在同一范围内的对象,用于锁定对它的所有访问。 (可能readers在这里可以很好地作为锁定对象本身,但是当这是一个好主意本身就是另一个主题时。)

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

如果这种同时使用是常见的,那么设计为容忍此类用途的并发字典会更好(框架中ConcurrentDictionary,或者我的ThreadsafeDictionary都可以工作)。这些通常效率较低,但在一定水平的并发使用之上效率更高。