更新并发字典中的元素时出现同步问题
本文关键字:同步 问题 元素 并发 字典 更新 | 更新日期: 2023-09-27 18:32:51
我有这段代码,我正在尝试更新并发字典中的项目(这是一个列表)以获取键(键始终相同)。
这是我的代码 -:
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 次代码中有 1 次抛出异常 - "源数组不够长。检查 srcIndex 和长度,以及数组的下限。
我知道这是列表的同步问题,但我不明白为什么会这样,因为并发字典是线程安全的。 所以我假设,它一次只允许一个线程更新我的列表,所以应该没有任何问题——:
我知道我错过了一些东西 - 请提出建议 - :
ConcurrentDictionary可以是线程安全的,但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 和头 #2 可以同时传递if (this._size == this._items.Length)
。线程 #1 将在此处设置值 this._items[this._size++] = item;
,但线程 #2 将导致 IndexOutOfRangeException。您需要线程安全列表。
更新 您可以使用"同步集合"而不是"列表"