在Dictionary使用foreach的注意
最近在对博客园的程序进行性能优化,在优化过程中用到了Dictionary,在通过foreach将Dictionary中的数据写入数据库时,遇到了这样的错误:
Collection was modified; enumeration operation may not execute.
代码类似这样的:
在执行foreach时,其他线程对_dictionary进行了Add操作,改变了_dictionary中的数据,从而产生了上述的异常信息。
通过Reflector查看Dictionary<TKey, TValue>.Enumerator.MoveNext()源代码,我们会发现开始处有这样的代码:
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++)
{
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~