zoukankan      html  css  js  c++  java
  • 在Dictionary使用foreach的注意

         最近在对博客园的程序进行性能优化,在优化过程中用到了Dictionary,在通过foreach将Dictionary中的数据写入数据库时,遇到了这样的错误:
         Collection was modified; enumeration operation may not execute.
         
         代码类似这样的:    
    Dictionary<intint> _dictionary = new Dictionary<intin>();
    //添加数据操作省略
    foreach(KeyValuePair<intint> item in _dictionary)
     {
     }

         在执行foreach时,其他线程对_dictionary进行了Add操作,改变了_dictionary中的数据,从而产生了上述的异常信息。

         那什么会产生这样的异常信息呢?
         foreach实际上执行的代码是:    

    Dictionary<intint>.Enumerator enumerator = _dictionary.GetEnumerator(); 
    try  

       
    while (enumerator.MoveNext())  
       { 
         
        } 

    finally  

       IDisposable d 
    = enumerator as IDisposable; 
       
    if (d != null) d.Dispose(); 
    }

         通过Reflector查看Dictionary<TKey, TValue>.Enumerator.MoveNext()源代码,我们会发现开始处有这样的代码:
    if (this.version != this.dictionary.version)
          {
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
          }

         而异常就是在这里发生的,因为Add操作时改变了Dictionary的version,通过查看Insert(TKey key, TValue value, bool add)的源代码会看出。
         我觉得Dictionary<TKey, TValue>应该提供一个方法,可以设置在MoveNext时是否进行版本检查,因为有时在foreach操作时,可能并不关心Dictionary中的数据是否被修改,我遇到的就是这样的情况,现在由于这个问题而不能使用foreach,而只能采取其他方法遍历Dictionary<TKey, TValue>中的数据。
         我采用的方法是:

    Dictionary<intint> _dictionary = new Dictionary<intin>();
    //添加数据操作省略
    int[] dataArray = new int[_dictionary.Values.Count];
    _ dictionary.Values.CopyTo(evcArray, 
    0)
    for (int i = 0; i < dataArray.Length; i++)
      {
       }
  • 相关阅读:
    第一个spring MVC
    AOP切点相关
    设计模式详解
    Spring基本原理模拟(IoC部分)
    AOP常用注解
    Integer.valueOf与Integer.parseInt的小疑惑
    IE10与IMG图片PNG显示不了 WP中的WebBrowser中无法查看PNG格式的图片
    去除Coding4Fun中MessagePrompt的边框(Border)
    windows phone 中的TextBlock的一些特性(TextWrapping,TextWrapping)
    九度 找出两个只出现了一次的数字
  • 原文地址:https://www.cnblogs.com/dudu/p/464391.html
Copyright © 2011-2022 走看看