我正在使用某个任务中的字典。
逻辑上我已经设置好了我的密钥永远不会发生冲突,但有时当我添加到字典时,我会得到这个例外。
Index was outside the bounds of the array.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Rpc.<MapIntoRpc>b__4[T](Object x) in Rpc.cs:line 113
at System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
我知道尝试删除或多次添加相同的密钥可能会出现并发问题,但我已经在算法上考虑了这一点。
导致添加有时失败的原因是什么? 解决这个问题的最佳方法是什么?
答案 0 :(得分:45)
您应该查看文档。它说的是:
只要不修改集合,词典就可以同时支持多个阅读器。即便如此,通过集合枚举本质上不是一个线程安全的过程。在枚举与写访问争用的极少数情况下,必须在整个枚举期间锁定该集合。要允许多个线程访问集合以进行读写,您必须实现自己的同步。 有关线程安全的替代方法,请参阅ConcurrentDictionary。
答案 1 :(得分:20)
您的问题很可能是同步问题。当向其添加词典时,有时需要增加底层结构(数组)的大小。如果要从多个线程添加可能导致IndexOutOfRangeException
的线程。您需要使用锁等以确保以安全的方式添加。
或者,您可以使用ConcurrentDictionary这是一个线程安全的集合。
答案 2 :(得分:15)