问题描述
我有这段代码,在这里我试图更新并发字典中的项(它是一个列表),以获取一个键(键始终是相同的).
I have this code, where I am trying to update item(which is a list) in my concurrent dictionary for a key (key is same all the time).
这是我的代码-:
class Program
{
private static readonly ConcurrentDictionary<string, List<int>> s_mapDatatypeToSource = new ConcurrentDictionary<string, List<int>>();
static void Main(string[] args)
{
try
{
Parallel.For(0, 10000000, i => AddItemToList(i, "local"));
}
catch (Exception exception)
{
Console.WriteLine(string.Format("Exception thrown ...{0}", exception.Message));
Console.ReadLine();
throw;
}
Console.WriteLine("Completed without exception");
Console.ReadLine();
}
private static void AddItemToList(int dataKey, string sourceName)
{
s_mapDatatypeToSource.AddOrUpdate(sourceName.ToUpperInvariant(), new List<int> { dataKey }, (s, list) =>
{
{
list.Add(dataKey);
return list;
}
});
}
}
上面代码的10倍中有一个抛出异常-源数组不够长.请检查srcIndex和length,以及数组的下限."
one out of 10 times above code is throwing exception - "Source array was not long enough. Check srcIndex and length, and the array's lower bounds."
我知道这是list的同步问题,但是我不明白为什么会这样,因为ConcurrentDictionary是线程安全的.所以我认为,它只允许一个线程一次更新我的列表,因此应该没有任何问题-:
I know this is a synchronization issue of list , but I am not getting why is this coming , since ConcurrentDictionary is thread safe. so I assume, it lets only one thread to update my list at one time, so there should not be any problem-:
我知道我想念一些东西-请提出建议-:
I know I am missing something - suggestions please -:
推荐答案
ConcurrentDictionary可以是线程安全的,但List不是.
ConcurrentDictionary can be thread-safe, but List is not.
从列表中查看反编译方法:
Look at decompiled method from List:
public void Add(T item)
{
if (this._size == this._items.Length)
this.EnsureCapacity(this._size + 1);
this._items[this._size++] = item;
++this._version;
}
线程#1和Thead#2可以同时通过if (this._size == this._items.Length)
.线程#1将在此处this._items[this._size++] = item;
设置值,但是线程#2将导致IndexOutOfRangeException.您需要线程安全列表.
Thread #1 and Thead #2 can pass if (this._size == this._items.Length)
at the same time. Thread #1 will set value here this._items[this._size++] = item;
, but Thread #2 will cause IndexOutOfRangeException. You need thread-safe list.
更新,您可以使用 SynchronizedCollection 而不是List
update You can use SynchronizedCollection instead of List
这篇关于更新ConcurrentDictionary中的元素时出现同步问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!