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:“注意到了,但我现在不担心线程问题”:我想这就是他删除它的原因。不过我更喜欢这个解释;我认为这更清楚