Collection was modified; enumeration operation may not execute.
代码类似这样的:
Dictionary
<
int
,
int
>
_dictionary
=
new
Dictionary
<
int
,
in
>
();
// 添加数据操作省略
foreach (KeyValuePair < int , int > item in _dictionary)
{
}
// 添加数据操作省略
foreach (KeyValuePair < int , int > item in _dictionary)
{
}
在执行foreach时,其他线程对_dictionary进行了Add操作,改变了_dictionary中的数据,从而产生了上述的异常信息。
那什么会产生这样的异常信息呢?
foreach实际上执行的代码是:
Dictionary
<
int
,
int
>
.Enumerator enumerator
=
_dictionary.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
}
}
finally
{
IDisposable d = enumerator as IDisposable;
if (d != null ) d.Dispose();
}
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);
}
{
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
<
int
,
int
>
_dictionary
=
new
Dictionary
<
int
,
in
>
();
// 添加数据操作省略
int [] dataArray = new int [_dictionary.Values.Count];
_ dictionary.Values.CopyTo(evcArray, 0 )
for ( int i = 0 ; i < dataArray.Length; i ++ )
{
}
// 添加数据操作省略
int [] dataArray = new int [_dictionary.Values.Count];
_ dictionary.Values.CopyTo(evcArray, 0 )
for ( int i = 0 ; i < dataArray.Length; i ++ )
{
}