简体   繁体   中英

C# yield return not returning an item as expected

I have following code:

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

private IEnumerable<MessageQueueItem> GetNextQueuedItem()
{
    if (_messageQueue.Count > 0)
        yield return _messageQueue.Dequeue();
}

Initially there is one item in the queue as ProcessQueue is called. During PerformAction, I would add more items to _messageQueue. However, the foreach loop quits after the initial item and does not see the subsequent items added.

I sense that somehow the initial state of the queue is being captured by yield.

Can someone explain what is happening and give a solution?

Your program does exactly what you instructed to do: it yields one item if Count > 0 - and yields zero items otherwise.

To return items until the queue becomes empty, try:

while (_messageQueue.Count > 0)

yield return actually pauses execution and does a fake return (it yields a value) until the next one is requested. In this case, what happens is you check if the count is > 0 and then yield the next value. When the next one is requested, your if statement isn't checked again, it returns to the line after the yield return which is the end of the method and thus it's done.

The definition of "YIELD"

Used in an iterator block to provide a value to the enumerator object or to signal the end of iteration.

I have an excellent record of reading syntax statements wrong but I think this means it has to be in an iterator block and the one you wrote is not.

Perhaps change your code to;

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM