2015-02-05 30 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