本文介绍了更新ConcurrentDictionary中的元素时出现同步问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码,在这里我试图更新并发字典中的项(它是一个列表),以获取一个键(键始终是相同的).

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中的元素时出现同步问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:14