【问题标题】:Collection was modified while enumeration [duplicate]枚举时修改了集合[重复]
【发布时间】:2012-04-30 21:44:57
【问题描述】:

可能重复:
Collection was modified; enumeration operation may not execute

我有一个通用列表,我在枚举时执行一些操作。

foreach(Action<string> action in actionList) 
{
    if(action != null) {
        action(mystring);
    }
}

现在我得到了这个异常:

InvalidOperationException:
Collection was modified; enumeration operation may not execute

如何解决这个问题,我被 .NET 3.5 钉牢了:/

【问题讨论】:

  • 查看页面右侧的“相关”栏,有大量相同的问题得到解答。

标签: c# list thread-safety action


【解决方案1】:

大概其中一个操作修改了actionList,使迭代器无效。避免错误的最简单方法是先获取列表的副本,例如

foreach(Action<string> action in actionList.ToList()) 
{
    if(action != null) {
        action(mystring);                               
    }
}

甚至:

foreach (var action in actionList.Where(action => action != null).ToList())
{
    action(mystring);
}

【讨论】:

  • +1。在不到 1 分钟的时间内回答 :)
  • 我尝试了你的第一个代码 sn-p 抛出 NullRefException :(
  • @Pascal:它不应该......它在哪里抛出异常?我假设actionList 本身是非空的?一个简短但完整的程序来演示这个问题真的很有帮助......
  • 我在第三方程序集中遇到的异常。
  • @Pascal:那么大概是某个地方的错误,或者你如何使用它......但我无法在你在这里给出的代码中修复它。这与您在此问题中给出的问题完全不同。
【解决方案2】:

您在迭代期间修改了 actionList。它可能是第二个线程,它与当前循环或进行修改或另一个迭代的操作方法不同步。所以解决方案可能是:

var tmp = new List<Action<string> >(actionList);
foreach(Action<string> action in tmp) 
{
    if(action != null) {
      action(mystring);                               
    }
}

但它只在动作修改的情况下才有效,在并行线程的情况下你应该同步列表。

【讨论】:

  • 与 Skeets 答案相同 => NullRefException
  • 我知道我是在 Skeets 发布他的答案时写的,所以我应该删除它吗?还提到问题可能出现在多线程环境中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多