12

我在多线程 .net 3.5 应用程序上始终收到此错误

错误 26 抛出异常。详细信息:'System.IndexOutOfRangeException:索引超出了数组的范围。

在 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)

在 System.Collections.Generic.Dictionary`2.Add(TKey 键,TValue 值)

我想我知道如何修复它(在适当的地方添加锁),但我希望能够在我的本地环境中重新创建这个问题,所以我会确保我修复它并且我能够添加一个单元测试为了它。

你知道任何一致的方式来重新创建这个吗?

4

4 回答 4

9
Dictionary<string, string> dict = new Dictionary<string, string>();

Task.Factory.StartNew(() => { while (true) dict["a"] = "a"; });
Task.Factory.StartNew(() => { while (true) dict.Remove("a"); });
于 2012-10-05T14:24:51.907 回答
4

不幸的是,在发生竞争条件的多线程应用程序中保持一致是根本无法实现的。

您的机器和生产机器之间的硬件差异将确保当问题确实发生时,它可能不在同一个位置。即使硬件相同,软件差异(尤其是那些后台服务)也会导致时间差异,从而导致无法重复的情况。

哎呀,如果这些线程依赖于外部资源(如数据库调用),那么生产和测试盒之间的网络延迟差异可能会确保您永远无法复制它。

羞于在服务器上安装调试器(坏主意),你能做的最好的事情是对代码进行可视化分析,修复你认为需要修复的部分,测试它(尽可能地)然后发布并在生产中观看。

于 2012-10-05T14:22:16.773 回答
1

这不会帮助您在本地重新创建错误,但要完全删除错误,通用Dictionary<TKey, TValue>的 msdn 文档说:

有关线程安全的替代方案,请参阅ConcurrentDictionary<TKey, TValue>

ConcurrentDictionary<TKey, TValue>的文档说:

表示可由多个线程同时访问的键值对的线程安全集合。

但是请注意, ConcurrentDictionary<TKey, TValue> 仅在 .Net 4 及更高版本中可用。

于 2012-10-05T14:27:14.760 回答
0

为什么不为字典创建一个包装器,其中包含 ReaderWriterLockSlim。这样,您就可以在一个班级中完成所有锁定。

于 2012-10-05T14:38:05.097 回答