我不需要从递归到非递归方式的课程,我只是想知道为什么我们不能处理这种类型的异常。无论如何,我在非常大的列表上使用递归函数。
我编写了试图捕获StackOverFlowExceptions的代码:
try { recursiveFxn(100000); }
catch(Exception){}
private void recursiveFxn(int countdown)
{
if (countdown > 0)
recursiveFxn(countdown - 1);
else
throw new Exception("lol. Forced exception.");
}
但我仍然遇到程序崩溃(在NUnit和我正在运行的网页中)。为什么没有抓住异常?
答案 0 :(得分:16)
自.NET Framework 2.0起,无法捕获StackOverflowException
。这是因为它被认为是一种不好的做法。引用MSDN documentation:
从.NET Framework开始 版本2.0,
StackOverflowException
try-catch无法捕获对象 块和相应的过程是 默认终止。所以, 建议用户编写代码 检测和防止堆栈 溢出。例如,如果你的 应用程序取决于递归,使用 反击或国家条件 终止递归循环。
现在,捕获StackOverflowException
的唯一方法是用户代码抛出它,如blog by Jared Parsons中所述。除此之外,通过hosting the CLR,您可以处理(但不能捕获)StackOverflowException
并设计一种方法来继续执行程序。
请注意,因为当发生异常时堆栈被展开,在.Net的2.0之前的版本中,当处理StackOverflowException
时堆栈实际上会更短,从而可以在不生成另一个StackOverflowException
的情况下执行此操作。 {1}}。
答案 1 :(得分:-1)
你无法捕获堆栈溢出异常,因为当它发生时会杀死线程死机。尝试... catch ...由同一个线程执行,这样就无法工作了。可能有一些较低级别的API可以P / Invoke并有另一个线程捕获它。 可能还有一些较低级别的API来更改最大堆栈大小,但我没有在.NET Framework中看到任何帮助,所以再次需要P / Invoke。