2015-02-05 21 views
0

我正面临一个令人不安的情况。字典中的空键键入

我有持有null键条目的字典...

null key in dictionary

出现这种情况,不时在我的IIS应用程序,当这本词典进行查询,然后冻结(100%的CPU,无限循环):FindEntry方法的

enter image description here

来源(未编译或reference sources)是相当清楚的:

1)具有在字典null键是不可能

2)的无限循环是很明显的给出我的字典私有字段:

private fields

任何想法就发生在我身上?

ps:我没有像ryujit或自定义.net构建安装任何有趣的东西。 只是一个普通的iisexpress .NET 4.5

编辑

按照要求(我应该有一种高精度)下运行:我没有做任何事情好笑本字典任。 只有一个用途:

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

如果我能看到你的代码,这将有所帮助。 – 2015-02-06 00:01:51

+0

@heh看到我的编辑...但我怀疑这将是有用的:/ – Olivier 2015-02-06 00:05:41

+0

虽然这个声明没有被锁定。 – Olivier 2015-02-06 00:11:21

回答

2

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

Dictionary与其他任何代码一样,写有关于之前发生的事情的假设。这些假设不考虑同时呼叫,例如,假定字典正在调整大小,调整大小将不会再发生,直到调整大小完成,一次只尝试设置一个给定的值,等等。

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

如果这样同时使用不会是共同的(和它似乎也不会),那么后卫锁每次访问:

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

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

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

如果这样的同时使用是常见的,那么旨在容忍这种使用的并发字典会更好(框架中的ConcurrentDictionary或我的ThreadsafeDictionary都可以)。这些通常效率较低,但在一定程度的并行使用之上效率更高。

+0

用一个不可变的字典替换它,实际上是:) – Olivier 2015-02-06 00:43:30

+0

(因为我不在意丢失我产生的值......这个字典只是用作缓存) – Olivier 2015-02-06 00:44:58

+0

这应该太好了。 – 2015-02-06 00:47:51