队列ForEach循环抛出InvalidOperationException

key*_*rdP 12 .net c# queue silverlight invalidoperationexception

我以前没有Queues<T>任何真正的学位,所以我可能会遗漏一些明显的东西.我试图迭代Queue<EnemyUserControl>这样(每一帧):

foreach (var e in qEnemy)
{
     //enemy AI code
}
Run Code Online (Sandbox Code Playgroud)

当敌人死亡时,敌方用户控制会引发我订阅的事件并执行此操作(队列中的第一个敌人被设计删除):

void Enemy_Killed(object sender, EventArgs e)
{      
     qEnemy.Dequeue();

     //Added TrimExcess to check if the error was caused by NULL values in the Queue (it wasn't :))
     qEnemy.TrimExcess();
}
Run Code Online (Sandbox Code Playgroud)

然而,出列方法被调用后,我得到InvalidOperationExceptionforeach循环.当我使用时Peek,没有错误,所以它必须对Queue本身的更改做一些事情,因为Dequeue删除了对象.我最初的猜测是,它正在抱怨我正在修改一个由Enumerator迭代的集合,但是这个集合是在循环之外执行的吗?

可能导致此问题的任何想法?

谢谢

Dar*_*rse 23

我知道这是一个老帖子,但以下内容如何:

var queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);

while (queue.Count > 0)
{
  var val = queue.Dequeue();
}
Run Code Online (Sandbox Code Playgroud)

干杯

  • 我建议稍微更改一下这个/ do而不是do/while,这样你就可以在尝试第一个.Dequeue()之前执行.Count检查,以防队列为空. (9认同)
  • 一个很好的答案!刚刚根据@DaveD 的关注对其进行了编辑 (2认同)

Ale*_*Aza 18

您正在修改foreach循环内的队列.这是导致异常的原因.
用于演示此问题的简化代码:

var queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);

foreach (var i in queue)
{
    queue.Dequeue();
}
Run Code Online (Sandbox Code Playgroud)

可能的解决方案是添加ToList(),如下所示:

foreach (var i in queue.ToList())
{
    queue.Dequeue();
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ris 5

旧帖子,但我想我会提供更好的答案:

var queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);


while (queue?.Count > 0))
{
  var val = queue.Dequeue();
}
Run Code Online (Sandbox Code Playgroud)

由于 DarkUrse 的原始答案使用了 do/while 并且在尝试在空队列上出队时如果队列为空会导致异常,因此还添加了针对空队列的保护

  • @AlexeyKhrenov 我的答案现已更新,以更好地解释其初衷......并且还添加了您提出的空检查。我希望这能澄清一切,谢谢 (2认同)