Queue is Always Empty Using yield return


I ran into an issue in a C# application the other day. Thankfully I figured out what was going wrong right away, but it could have turned into a big headache potentially.

The View was strongly typed as IEnumerable and looked something like this:

<% if(Model.Any()) { %>
<ul id="messages">
<% foreach (var message in Model) { %>
    <li><%: message %></li>
<% } %>
</ul>
<% } %>

The code behind for putting the Model into the view was also pretty simple:

`</p>

public ActionResult Messages()
{
	return PartialView(messageService.GetMessages());
}

` 

The implementation of MessageService was also very simple:

`</p>

public IEnumerable GetMessages()
{
	while (Queue.Count > 0)
		yield return Queue.Dequeue();
}

` </pre> 

I could set a breakpoint and see messages being queued up, but the list items weren't being rendered on the page. See the problem?

The issue isn't in the Messages() action or the GetMessages() method. In the view, when .Any() is called, it will enumerate the collection and dequeue all the messages. After that happens, there is nothing to loop through in the foreach. This was fixed easy enough with the following in MessageService:

`</p>
public IEnumerable GetMessages()
{
	return GetDequeuedMessages().ToArray();
}

private static IEnumerable GetDequeuedMessages()
{
	while (Queue.Count > 0)
		yield return Queue.Dequeue();
}

` </pre> 

Hopefully this helps you from pulling your hair out if you didn't catch it right away!
Using AppHarbor for Continuous Integration