Dictionary<int, int> dic = new Dictionary<int, int>();
Parallel.For(0, 10000, (i) =>
{
dic.Add(i, i);
});
上面这段代码有时有异常,出现的频率是执行5次会产生一次异常(在本机),为什么会产生异常而且是两种截然不同的异常
第一种:
System.AggregateException : 发生一个或多个错误。 ----> System.IndexOutOfRangeException : 索引超出了数组界限。
第二种:
System.AggregateException : 发生一个或多个错误。
----> System.ArgumentException : 目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。
这是因为Dictionary不是线程安全的,而你的并行程序会有可能多个线程同时操作它。C#4建议用ConcurrentDictionary<K,V>,早期版本只能自己实现一个线程安全的字典了。
那这中间为什么会出现这种错误呢,而且是数组的,字典的底层实现方式吗?请问字典的实现原理有是什么呢?
System.Collections.Concurrent.ConcurrentDictionary<int, int> dic = new System.Collections.Concurrent.ConcurrentDictionary<int, int>();
System.Threading.Tasks.Parallel.For(0, 10000, (i) =>
{
dic.AddOrUpdate(i,i,(k,v)=>v);
});
那这中间为什么会出现这种错误呢,而且是数组的,字典的底层实现方式吗?请问字典的实现原理有是什么呢?
@az235: 你看下这个,有很详细的原理说明。http://www.xueit.com/cshare/show-6804-1.aspx
里面有一句“
当再次插入数据时,会首先查找freeList链表,以提高查找entries中空闲数据项位置的效率。在枚举器中,枚举顺序为entries数组的下标递增顺序。
”。现在并发的时候,就容易引起枚举的错误。