1

In the MSDN and Intellisense info there is no mention of any Exception that is thrown when calling Queue.Enqueue method

But since MSDN says

.....As elements are added to a Queue, the capacity is automatically increased as required through reallocation

I guess it can failed because there is not enough memory to hold the new element.

What other errors can happen when callin Queue.Enqueue method ? Maybe the answer could include a LINK to documentation that list all of them for this particular method

How can I catch/handle the OutOfMemoryException when calling that method even though is not being thrown ? (Even if I can not recover from the OutOfMemory error I want to log it)

And by "not being thrown" I mean that

In the documentation of any method it always mentions what exceptions can be thrown by that method, but for that particular method is either not documented or it does not throw any exception. I want to know which one it is

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
  • 1
    What do you mean by "even though it is not being thrown"? If it's not being thrown, there's nothing to catch. Generally speaking, if your process has run out of memory you're unlikely to be able to recover anyway... – Jon Skeet Jan 16 '14 at 14:38
  • @JonSkeet in the documentation of any method it always mentions what exceptions can be thrown by that method...well for that particular method is either not documented or id does not throw any exception – Mauricio Gracia Gutierrez Jan 16 '14 at 14:40
  • Are you primarily a Java programmer by any chance? If so, C# does not have the same concept of checked exceptions - any exception can be thrown from any method, although the documentation *may* indicate *likely* exceptions. Similarly, you can catch any type of exception from any block of code - the compiler will not complain! – RB. Jan 16 '14 at 14:40
  • @RB So If I wrap it arround a try/catch I can posibly catch expections even if they are not mentioned in the documentation ? And yes I started with Java long time ago – Mauricio Gracia Gutierrez Jan 16 '14 at 14:46
  • 1
    @MauricioGracia: How often have you seen `OutOfMemoryException` documented? Bear in mind that an *awful* lot of methods allocate memory... and all of them could fail if they run out of memory. – Jon Skeet Jan 16 '14 at 14:49
  • 1
    @MauricioGracia Yes - please see the edit to my answer where I've put an example. The documentation is purely a guide to what *may* be thrown - it's not part of a compiler-enforcable contract, and the implementation may throw more exception types, or even fewer if it wants to. Please read the answers to [this question](http://stackoverflow.com/questions/178456/what-is-the-proper-way-to-re-throw-an-exception-in-c) for more information. – RB. Jan 16 '14 at 14:53

3 Answers3

1

Here is the disassembly of the Enqueue method (taken from ILSpy)

public void Enqueue(T item)
{
    if (this._size == this._array.Length)
    {
        int num = (int)((long)this._array.Length * 200L / 100L);
        if (num < this._array.Length + 4)
        {
            num = this._array.Length + 4;
        }
        this.SetCapacity(num);
    }
    this._array[this._tail] = item;
    this._tail = (this._tail + 1) % this._array.Length;
    this._size++;
    this._version++;
}

private void SetCapacity(int capacity)
{
    T[] array = new T[capacity];
    if (this._size > 0)
    {
        if (this._head < this._tail)
        {
            Array.Copy(this._array, this._head, array, 0, this._size);
        }
        else
        {
            Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head);
            Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail);
        }
    }
    this._array = array;
    this._head = 0;
    this._tail = ((this._size == capacity) ? 0 : this._size);
    this._version++;
}

As you can see, it's pretty straightforward. You could get a StackOverflowException, or an OutOfMemoryException because you can always potentially get these.

Apart from that, it's not clear that anything could go wrong. You'd need to verify that there was no possibility of a NullPointerException by validating the various checks and guard clauses in the rest of the code, but a cursory glance suggests it is likely this will not occur. Of course, if you start using reflection you could always force a NullPointerException to throw.

I don't know if this will help you, but I believe it answers the question you've asked.

RB.
  • 36,301
  • 12
  • 91
  • 131
  • 1
    I'm getting an Exception on the Array.Copy in SetCapacity, because _head + _size goes beyond the end of _array. Can't work out how this *could* work at the moment. – Benjol Oct 26 '20 at 06:29
0

Having seen your edit, the question makes a bit more sense.

The MSDN documentation does not ordinarily document that OutOfMemoryException can be thrown as, basically, any method call could throw it (any method that allocates memory anyway - which is pretty much all of them!). Therefore, you can assume that it can be thrown in this case.


To clarify the situation with catching exceptions, imagine this bit of code:

  try
  {
      throw new ArgumentNullException();
  }
  catch (ArgumentOutOfRangeException)
  { 
      // This can never happen, but is perfectly legal code.
  }

The catch block will never be entered, but the compiler is perfectly happy with this code - it won't even issue a warning.

RB.
  • 36,301
  • 12
  • 91
  • 131
  • consider the title of the question. I already know the try/catch pattern but I am looking for the posible errors that can happend when calling Enqueue – Mauricio Gracia Gutierrez Jan 16 '14 at 16:16
  • The documentation is the correct place to look - but it does not necessarily list all the possible exceptions that may occur (especially for exceptions that can be thrown by anything, such as OutOfMemory or StackOverflow). That's just how .NET works... – RB. Jan 16 '14 at 16:30
  • I try to google for other trusted places where this could be found but no luck. But maybe theres is a forum post out there with what I am looking for. Thanks – Mauricio Gracia Gutierrez Jan 16 '14 at 16:41
0

If your only goal is to catch all possible execptions and log them and do nothing else it is actually quite simple to do.

try
{
    queue.Enqueue(foo);
}
catch (Exception ex)
{
    LoggingMethod(ex);
    throw;
}

What that will do is catch all exceptions that are possible to catch (OutOfMemory is one of the few you may not be able to), log it, then re-throw the exception while preserving the original stack trace so the code this snippet resides in can handle it if necessary.

Do not do throw ex;, that causes the stack trace to be re-created to point at your throw ex line and you won't know which line of code the real exception was thrown from.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • 1
    Scott Chamberlain my only goal is not just to catch any error but to understand what errors can happen when callin Enqueue method and try to handle them. Maybe links to where this is documented – Mauricio Gracia Gutierrez Jan 16 '14 at 15:38