【问题标题】:foreach loop - collection was modified exceptionforeach 循环 - 集合被修改异常
【发布时间】:2014-09-19 03:03:33
【问题描述】:

我遇到了错误:

System.InvalidOperationException:集合已修改;枚举操作可能无法执行。

在我的代码中,有一些字符、对象等的哈希表需要不断地读取和删除。我的代码使用foreach 循环对哈希表中的所有值执行某些操作,但是说一个字符注销,因为foreach 正在循环...并且哈希表已修改...繁荣,错误。

请注意,任何直接修改哈希表的foreach 代码都会被复制到列表中,并从那里编辑父列表,这不是问题。问题是读取不断编辑的哈希表。

所以我了解什么问题是什么,只是不是解决问题的最佳方法。下面是一个偶尔会抛出集合修改错误的简单代码示例:

foreach (Character CC in World.H_Chars.Values)
{
   if (CC.MyGuild != null && CC.MyGuild.GuildName != G.GuildName
      && CC.MyGuild.Allies.ContainsValue(G.GuildName))
   {
      CC.MyClient.AddSend(Data); // error on this line
      CC.MyClient.EndSend();
   }
}

所以我想我的问题是,通过不断修改的对象哈希表的最佳方法是什么?

【问题讨论】:

  • 所以 .. 你的意思是你希望它是线程安全的?
  • 是的,我想,如果这样可以解决问题。

标签: c# loops exception collections foreach


【解决方案1】:

您可以尝试使用System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>。这是一个线程安全的键值对数据结构(例如,它是一个通用的 HashTable 类型实现——它具有 O(1) 的元素查找)。它可以在枚举时更新。但是,您确实需要注意,在枚举这种类型的集合时,您可能会得到“脏”读取(即,您正在迭代的集合是迭代开始时字典的快照 - 因此发生更新在您开始迭代之后可能在当前的集合迭代中不可见)。

还有一个System.Collections.Concurrent.ConcurrentBag<T>,它是System.Collections.Generic.List<T> 的线程安全等效项。

【讨论】:

    【解决方案2】:

    So I guess my question is what's the best way to go through a Hashtable of Objects that's constantly being modified?

    我怀疑最好的方法是不这样做。 :)

    考虑以另一种方式看待问题。例如,我看到您正在寻找具有某些特征的数据,这可能是由于对您提到的哈希表的不断修改造成的。这些修改是事件。如果您可以安排诸如首先对这些事件做出反应的事情,那将解决不断变化的哈希表随后存储它们的问题。

    【讨论】:

    • 这个例子很好。我已经重写了它以从不太经常变化的盟友列表而不是世界列表中提取盟友角色。所以这个错误可能已经解决了。我仍然希望对 foreach / modify 异常有更好的修复,因为我正在使用的代码大量使用 foreach 语句,并且为所有这些语句寻找替代方案将非常耗时。
    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    相关资源
    最近更新 更多