使用并发字典 - 线程安全集合修改

Mis*_*tyD 7 c# concurrency

最近,当使用通用字典时,我遇到了以下异常

发生InvalidOperationException.一个集合被修改

我意识到这个错误主要是因为我正在使用的静态字典上的线程安全问题.

一点背景:我目前有一个应用程序有3种不同的方法与这个问题有关.

  1. 方法A使用字典迭代foreach并返回一个值.
  2. 方法B将数据添加到字典中.
  3. 方法C更改字典中键的值.

有时在迭代字典时,也会添加数据,这是导致此问题的原因.我继续在foreach我的代码中获取此异常,我遍历字典的内容.为了解决这个问题,我用通用字典取代了ConcurrentDictionary,这里是我所做的细节.

目标:我的主要目标是完全删除异常

对于方法B(向字典添加新密钥),我替换.AddTryAdd

对于方法C(更新字典的值),我没有做任何更改.代码的草图如下:

  static public int ChangeContent(int para)
  {
      foreach (KeyValuePair<string, CustObject> pair in static_container)
      {
             if (pair.Value.propA != para ) //Pending cancel 
             {
                pair.Value.data_id = prim_id;    //I am updating the content
                return 0;

             }
      }
     return -2;
  }
Run Code Online (Sandbox Code Playgroud)

对于方法A - 我只是迭代字典,这是运行代码停止的地方(在调试模式下),Visual Studio告诉我这是发生错误的地方.我使用的代码类似于以下

    static public CustObject RetrieveOrderDetails(int para)
    {
            foreach (KeyValuePair<string, CustObject> pair in static_container)
            {                   
                if (pair.Value.cust_id.Equals(symbol))
                {
                    if (pair.Value.OrderStatus != para) 
                    {
                       return pair.Value; //Found
                    }
                }
            }
            return null; //Not found
    }
Run Code Online (Sandbox Code Playgroud)

这些更改是否会解决我得到的异常.

编辑:

它在此页面上指出该方法GetEnumerator允许您与写入并行遍历元素(尽管它可能已过时).和使用foreach一样吗?

sll*_*sll 1

在尝试foreach()将容器复制到新实例之前

var unboundContainer = static_container.ToList();
foreach (KeyValuePair<string, CustObject> pair in unboundContainer)
Run Code Online (Sandbox Code Playgroud)

另外,我认为Value从线程安全的角度来看更新属性是不正确的,请重构您的代码以TryUpdate()代替使用。