已知字典不是线程安全的,所以您应该同步写入和读取。但是,如果你想要的东西可以去错了具体的例子 - 考虑这个小应用程序:
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