错误信息:     集合已修改;可能无法执行枚举操作 

 调用堆栈:   

 在 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)    

 在 System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()

 

这个错误是怎么引发的?

我们具体分析一下Dictionary的内部实现。

  public class Dictionary<TKey, TValue>

    {

        //字典的版本号

        private int version;

 

        public void Clear()

        {

            //执行这个操作后,版本号加一,版本发生变化

            this.version++;

        }

 

        private void Insert(TKey key, TValue value, bool add)

        {

            //执行这个操作后,版本号加一,版本发生变化

            this.version++;

        }

 

        public bool Remove(TKey key)

        {

            //执行这个操作后,版本号加一,版本发生变化

            this.version++;

        }

 

        public void Add(TKey key, TValue value)

        {

            //执行这个操作后,版本号加一,版本发生变化

            this.Insert(key, value, true);

        }

 

        public struct Enumerator

        {

            private Dictionary<TKey, TValue> dictionary;

            //Enumerator的版本号

            private int version;

 

            internal Enumerator(Dictionary<TKey, TValue> dictionary)

            {

                this.dictionary = dictionary;

                //初始化时,把当时dictionary.version传给Enumerator的version

                this.version = dictionary.version;

            }

 

            public bool MoveNext()

            {

                //如果dictionary.version发生变化,就会抛出上面的异常

                if (this.version != this.dictionary.version)

                {

                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);

                }

 

            }

        }

 

通过分析源码可以知道,只要dictionary.version发生变化,在做foreach循环时,就会抛出上面的错误。

 

具体来说,在做foreach循环时,dictionary对象发生Clear、Insert、Remove、Add操作时,就会引发上面的异常。

 

如果代码场景涉及到并发操作,推荐用并发字典ConcurrentDictionary,不要自己加锁控制并发。

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
  • 2022-01-16
猜你喜欢
  • 2021-10-16
  • 2021-09-24
  • 2021-11-22
  • 2021-08-21
  • 2022-12-23
相关资源
相似解决方案