在MSDN和Intellisense信息中,没有提到调用Queue.Enqueue
方法时抛出的任何异常
但是自从MSDN说
.....当元素添加到队列时,容量会根据需要通过重新分配自动增加
我想它可能会失败,因为没有足够的内存来容纳新元素。
callin Queue.Enqueue
方法可能会发生哪些其他错误?
也许答案可能包括链接到文档列出所有这些特定方法的文档
即使没有抛出该方法,如何在调用该方法时捕获/处理OutOfMemoryException?(即使我无法从OutOfMemory错误中恢复,我想记录它)
并且“不被抛出”我的意思是
在任何方法的文档中,它总是提到该方法可以抛出哪些异常,但是对于该特定方法要么没有记录,要么它不会抛出任何异常。我想知道它是哪一个
答案 0 :(得分:1)
以下是Enqueue方法的反汇编(取自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++;
}
正如您所看到的,它非常简单。您可以获得StackOverflowException或OutOfMemoryException,因为您总是可能会获得这些内容。
除此之外,不清楚任何事情都可能出错。您需要通过验证其余代码中的各种检查和保护子句来验证不存在NullPointerException的可能性,但粗略的一瞥表明这可能不会发生。当然,如果你开始使用反射,你总是可以强制抛出NullPointerException。
我不知道这会对你有所帮助,但我相信它会回答你提出的问题。
答案 1 :(得分:0)
看过你的编辑后,问题会更有意义。
MSDN文档通常不会记录可以抛出OutOfMemoryException,因为基本上,任何方法调用都可以抛出它(任何分配内存的方法 - 这几乎都是它们!)。因此,您可以假设在这种情况下可以抛出它。
为了澄清捕获异常的情况,想象一下这段代码:
try
{
throw new ArgumentNullException();
}
catch (ArgumentOutOfRangeException)
{
// This can never happen, but is perfectly legal code.
}
永远不会输入catch块,但编译器对此代码非常满意 - 它甚至不会发出警告。
答案 2 :(得分:0)
如果您的唯一目标是捕获所有可能的exec并记录它们而不执行任何其他操作,那么它实际上非常简单。
try
{
queue.Enqueue(foo);
}
catch (Exception ex)
{
LoggingMethod(ex);
throw;
}
它将捕获所有可能捕获的异常(OutOfMemory是您可能无法做到的少数异常之一),记录它,然后在保留原始堆栈跟踪的同时重新抛出异常,因此代码为如果需要,可以处理它的代码片段。
不执行throw ex;
,这会导致重新创建堆栈跟踪以指向throw ex
行,并且您将不知道哪一行代码真正的例外被抛出。