Mus*_*hin 3 .net c# multithreading dictionary
所以在http://msdn.microsoft.com/en-us/library/xfhwa508.aspx的底部我们看到
只要不修改集合,Dictionary(Of 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是线程问题的一部分 - 错误不一定可靠地重现.问题是插入必须达到特定的竞争条件,这显然不会在您的测试中发生.当然,足够的运行可能会导致触发,但这将难以可靠地测试.
话虽如此,这显然是一个问题.你应该考虑如何纠正它,而不是专注于复制它.当然,这里显而易见的答案是切换到另一种技术,例如使用ConcurrentDictionary<T,U>替代技术,这是线程安全的.