【问题标题】:Linq strange behaviorLinq 奇怪的行为
【发布时间】:2015-11-25 08:43:23
【问题描述】:

声明:

(definitions != null && definitions.Where(key => key.asset_id != null &&
                                          key.asset_id == item).FirstOrDefault() != null

投掷:

集合被修改枚举操作可能无法执行

如何解决这个问题?

if (definitions != null 
    && definitions
         .Where(key => key.asset_id != null && key.asset_id == item)
         .FirstOrDefault() != null)
{
    CurrentDuration = definitions
                        .Where(key => key.asset_id != null && key.asset_id == item)
                        .FirstOrDefault().duration;
}

【问题讨论】:

  • 你是否在任何循环中运行它?
  • 这部分在函数DrawBox()里面,这个函数在foreach里面。是的。
  • 嗯,有些东西正在动态修改您的定义集合,这会破坏 foreach。如果没有看到该循环,就不可能提出更改建议,但您可以将您对集合的预期更改存储在变量或字典中,然后在循环完成后实现它们。
  • 您应该从使用变量开始。您正在多次执行 LINQ 查询。
  • 不要害怕自己尝试解释异常。 collection was modified enumeration operation may not execute - 从您发布的相关代码中,唯一的“集合”是definitions。该集合正在修改(您知道修改的含义),因此枚举(“循环”)可能无法执行(“继续”)。即您的代码中的某些内容正在修改该集合,同时它循环它。由于我比您的问题更信任异常,因此建议您从示例中省略重要代码。我假设你在foreach 中设置了一些东西。

标签: c# linq


【解决方案1】:

问题是在您的代码中某处definitions 集合被修改。主要是因为另一个线程中的集合修改,但也可能有其他一些原因。您应该找出在其他地方修改集合的代码。无论您使用的是definitions,您都可以使用lock 保护definitions 变量。

if (definitions != null)
{
    lock (definiitons)
    {
        var definition = definitions.FirstOrDefault(key => key.asset_id != null && key.asset_id == item);
        if (definition != null)
            CurrentDuration = definition.duration;
    }
}

并在您修改 definitions 或其引用的任何地方加锁,例如:

lock (definitions)
{
    definitions.Add(x);
}

lock (definitions)
{
    definitions.Remove(x);
}

甚至

var otherRef = definitions
lock (otherRef )
{
    otherRef .Add(x);
}

【讨论】:

    【解决方案2】:

    我假设“CurrentDuration”是一个 foreach 循环变量计数器。

    foreach 语句用于遍历集合以获取所需的信息,但不能用于从源集合中添加、删除或更改项目,以避免不可预知的副作用。如果您需要从源集合中添加、删除或更改项目,请使用 for 循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多