C#收益返回未按预期返回项目

C#收益返回未按预期返回项目,c#,yield,C#,Yield,我有以下代码: private void ProcessQueue() { foreach (MessageQueueItem item in GetNextQueuedItem()) PerformAction(item); } private IEnumerable<MessageQueueItem> GetNextQueuedItem() { if (_messageQueue.Count > 0) yield retur

我有以下代码:

private void ProcessQueue()
{
    foreach (MessageQueueItem item in GetNextQueuedItem())
        PerformAction(item);
}

private IEnumerable<MessageQueueItem> GetNextQueuedItem()
{
    if (_messageQueue.Count > 0)
        yield return _messageQueue.Dequeue();
}
private void ProcessQueue()
{
foreach(GetNextQueuedItem()中的MessageQueueItem项)
绩效(项目);
}
私有IEnumerable GetNextQueudItem()
{
如果(_messageQueue.Count>0)
产生返回_messageQueue.Dequeue();
}
最初,在调用ProcessQueue时,队列中有一个项目。 在执行期间,我会将更多项目添加到_messageQueue。但是,foreach循环在初始项之后退出,并且看不到添加的后续项

我感觉到队列的初始状态被yield捕获了


有人能解释发生了什么并给出解决方案吗?

您的程序完全按照您的指示执行:如果计数为0,则生成一项,否则生成零项

要返回项目直到队列变为空,请尝试:

while (_messageQueue.Count > 0)

yield return
实际上暂停执行并执行假返回(它生成一个值),直到请求下一个返回为止。在这种情况下,将检查计数是否大于0,然后生成下一个值。当请求下一个时,if语句不会再次被选中,它会返回到
yield return
之后的行,这是方法的结尾,因此它就完成了。

yield的定义

在迭代器块中用于向枚举器对象提供值或发出迭代结束的信号

我有很好的错误读取语法语句的记录,但我认为这意味着它必须在迭代器块中,而您编写的不是

也许将代码更改为

foreeach (MessageQueItem item In GetNextQuedItem()
{
     if (_messageQueue.Count > 0)
     {   
         yield return _messageQueue.Dequeue();
     } else { 
         yield break;
     }

}

如果只在ProcessQueue中使用while循环而不是使用枚举器,那么代码会更简单。枚举数非常方便,但对于简单的循环处理来说,它们可能是多余的。很好的评论-尽管我是通过一系列重构得出上述结论的,我只是被好奇心所吸引。@Obalix:你错了。永远不会有竞争条件,因为项目是在同一线程的执行过程中添加的。问题不在于从其他线程访问队列,
yield
不会神奇地将代码变成多线程。关于竞态条件的一点在哪里???@Jiho:如果队列可以由多个线程同时访问和/或修改,您发布的代码将无法按预期工作。注意到,但我目前不关心线程问题。至于我关于比赛条件的问题,我的意思是我不知道奥巴利克斯在哪里谈论比赛条件。不知怎么删除了吗?@Jiho:“注意到了,但我现在不担心线程问题”:我想这就是他删除它的原因。不过我更喜欢这个解释;我认为这更清楚