更新并发字典中的元素时出现同步问题

本文关键字:同步 问题 元素 并发 字典 更新 | 更新日期: 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。您需要线程安全列表。

更新 您可以使用"同步集合"而不是"列表"