Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Queue.Peek throws InvalidOperationException if Queue is Empty

Tags:

c#

I've got a simple Queue to manage items being added to my application.

From Microsoft's current documentation of their Queue.Peek Method:

screenshot

What is the point of using Peek() to look at the Queue if it still throws an Invalid Operation Exception?

I thought the whole point of Peek() was to have code that did NOT generate exceptions.

like image 392
jp2code Avatar asked Sep 02 '14 22:09

jp2code


2 Answers

Even MSDN mentions the reason:

null can be added to the Queue as a value. To distinguish between a null value and the end of the Queue, check the Count property or catch the InvalidOperationException, which is thrown when the Queue is empty.

So the reason for a queue to throw an exception if you try to peek at the first item is that it could be null. How do you want to distinguish between a valid null value and no item?

The same is true if the queue contains value types like int. Should it return -1 if there is no item to peek at? No, -1 could be a valid value so you don't know if there is another item in the queue.

Instead use the Count property to check whether or not the queue is empty:

var queue = new Queue<int>();
queue.Enqueue(-1);
while (queue.Count > 0)
{
    int current = queue.Peek();         // still in the queue
    Console.WriteLine(queue.Dequeue()); // now empty
}

I assume that you're confusing queue.Peek with a method like dataReader.Read. The difference is that Read advances the reader to the next record and just returns a bool which indicates whether or not there was a record at all. Queue.Peek also returns that "record". It's a different purpose, so don't use Peek if you want to know if there is one.

By the way, this behaviour is consistent in the framework. Other methods like Enumerable.First also throw an InvalidOperationException if you use them on an empty sequence.

like image 151
Tim Schmelter Avatar answered Sep 18 '22 01:09

Tim Schmelter


The point of Peek is to look at the next element of the queue, without removing it. The fact that it is not removed is the main difference between Peek and Pop (Dequeue in .NET). (That's nothing to do with .NET; for any language's queue structure which has a Pop (/Dequeue) which returns the popped value, that's the difference between the two.

If the queue is empty, there is nothing reasonable that Queue can return. An exception is the only alternative to returning a value, so that's the appropriate behavior. Either catch and handle the exception, or (if you're not worried about race conditions) check whether the queue is empty before calling Peek/Dequeue.

like image 37
Sneftel Avatar answered Sep 18 '22 01:09

Sneftel