已知字典不是線程安全的,所以您應該同步寫入和讀取。但是,如果你想要的東西可以去錯了具體的例子 - 考慮這個小應用程序:
static void Main(string[] args) {
var dict = new Dictionary<int, int>();
dict.Add(0, 0);
new Thread(() => {
for (int i = 1; i < int.MaxValue; i++) {
lock (dict) {
dict.Add(i, i);
dict.Remove(i);
}
}
}).Start();
new Thread(() => {
while (true) {
if (!dict.ContainsKey(0))
throw new Exception("cannot happen?");
}
}).Start();
Console.ReadKey();
}
我們創建字典與關鍵0
一個條目,然後我們運行兩個線程。第一個線程不斷地向字典中添加和刪除鍵,但注意它不會刪除帶有鍵0的項目。鍵爲0的項目始終存在。
第二個線程不斷檢查是否有鍵0的項目,如果沒有則拋出異常。您可能會認爲這絕不會發生,因爲我們從不刪除項目中的鍵0,但事實並非如此。如果你將運行這個應用程序,它會拋出「不可能發生?」異常幾乎立即。如果你在ContainsKey
附近加鎖 - 這絕不會發生。
因此,簡而言之,如果您沒有正確地同步訪問線程安全結構,即使是讀取,也可能會出現可怕的錯誤。而且你甚至可能沒有注意到這一點,並且將很難調試這些問題,因爲應用程序可能表現得像一切都很好。
來源
2017-04-14 18:14:03
Evk
'Dictionary'通常不是線程安全的。如果您需要線程安全字典,請使用'ConcurrentDictionary'。 –
字典不是線程安全的。 ConcurrentDictionaries是 –
如果您從多個線程編寫和讀取字典 - 寫入和讀取都不是線程安全的 – Evk