所以在http://msdn.microsoft.com/en-us/library/xfhwa508.aspx底部我們看到與字典不安全線程 - 讓我們打破一些東西
一個詞典(TKEY的,TValue)可以同時支持多個閱讀器,只要收集不被修改。即便如此,枚舉集合本質上不是一個線程安全的過程。在枚舉與寫入訪問競爭的罕見情況下,集合必須在整個枚舉期間被鎖定。爲了讓集合可以被多個線程讀取和寫入,您必須實現自己的同步。
在我的asp.net應用程序中,我偶爾會看到從System.Collections.Generic.Dictionary`2.Insert中生成的NullReferenceExceptions。
我該如何在沙箱中重新創建?
儘管本地字典被單獨的線程訪問,但以下代碼不會導致該異常。
class Program {
static void Main(string[] args) {
int maxThreads = 20;
Dictionary<Guid, Guid> dict = new Dictionary<Guid, Guid>();
var tws = new threadWithState();
while (true) {
for (int i = 0; i < maxThreads * 2; i++) {
var thread = new Thread(tws.Work);
thread.IsBackground = true;
thread.Start(dict);
}
dict[Guid.NewGuid()] = Guid.NewGuid();
}
}
}
class threadWithState {
public void Work(object dict) {
Console.WriteLine((dict as Dictionary<Guid, Guid>).Count);
for (int i = 0; i < 1000; i++) {
(dict as Dictionary<Guid, Guid>)[Guid.NewGuid()] = Guid.NewGuid();
}
}
}
這是有道理的,但它產生了一個不同的例外。 IndexOutOfBounds而不是NullReferenceException。 – MushinNoShin 2011-12-23 20:02:08
是的,肯定有不止一種方式會因爲不使用鎖而破壞課程。請注意,您不是模擬閱讀,更可能會生成NRE。我會說,一種失敗模式就夠了。 – 2011-12-23 20:13:16