C#-如何处理/捕获StackOverflowException?

C#-如何处理/捕获StackOverflowException?,c#,exception-handling,recursion,C#,Exception Handling,Recursion,我不需要从递归方法转换到非递归方法,我只想知道为什么我们不能处理这种类型的异常。无论如何,我在非常大的列表上使用递归函数 我已编写代码尝试捕获StackOverflowException: try { recursiveFxn(100000); } catch(Exception){} 但我仍然会遇到程序崩溃(在NUnit和我正在运行的网页中)。为什么没有捕获异常?自从.NET Framework 2.0以来,StackOverflowException无法捕获。这是因为这被认为是一种不好的做法

我不需要从递归方法转换到非递归方法,我只想知道为什么我们不能处理这种类型的异常。无论如何,我在非常大的列表上使用递归函数

我已编写代码尝试捕获StackOverflowException:

try { recursiveFxn(100000); }
catch(Exception){}

但我仍然会遇到程序崩溃(在NUnit和我正在运行的网页中)。为什么没有捕获异常?

自从.NET Framework 2.0以来,
StackOverflowException
无法捕获。这是因为这被认为是一种不好的做法。引述:

从.NET框架开始 版本2.0,a
StackOverflowException
对象不能被try-catch捕获 块,相应的进程是 默认终止。因此,, 建议用户编写自己的代码 检测并防止堆栈 溢流例如,如果您的 应用程序依赖于递归,请使用 计数器或状态条件 终止递归循环

现在,捕获
StackOverflowException
的唯一方法是当它被用户代码抛出时,如一篇文章中所述。除此之外,通过,您可以处理(但不能捕获)一个
StackOverflowException
,并设计一种方法让程序继续执行


请注意,由于堆栈在异常发生时展开,因此在.Net 2.0之前的版本中,当处理
StackOverflowException
时,堆栈实际上要短得多,如果不生成另一个
StackOverflowException

就可以执行此操作,则无法捕获堆栈溢出异常,因为发生此异常时会导致线程死机。尝试抓住。。。是由同一个线程执行的,因此不起作用。可能有一些较低级别的API,您可以P/Invoke并让另一个线程捕获它。
也可能有一些较低级别的API来更改最大堆栈大小,但我在.NET Framework中没有看到任何帮助,因此您同样需要P/调用某些东西。

我有点惊讶于存在此异常。。。在托管代码之外,我不相信一般情况下可以从这个错误中恢复。@RobertKarl:我希望有一种方法,代码可以显式地检查堆栈是否有一定的空间,如果空间不可用,就会抛出异常。如果这样的方法在堆栈溢出之前抛出异常,并且如果请求的空间量至少等于将在测试之间分配的最大堆栈数加上恢复代码所需的量之和,则此类异常可以100%恢复。事实上,我知道没有任何方法可以编写不人为限制其可处理结构深度的安全递归代码。-1因为正如我上面所指出的,堆栈溢出异常可能会在早期版本的.Net中被捕获,因此您关于它“因为在同一线程上而无法工作”的回答是错误的。@Virtlink:如果我没有记错,在.NET1.0中,如果试图捕获
StackOverflowException
,它将“通常”起作用。然而,在线程上下文被破坏到无法修复之前,允许捕获这些异常“通常”会带来很大的开销,尽管有这样的开销,但该特性仍然不够可靠,无法发挥作用。在.NET2.0中,微软决定要求程序员使用其他方法从这种情况中恢复,而不是产生额外的开销,这样他们就可以尝试使用一种可能无论如何都不起作用的恢复方法。
private void recursiveFxn(int countdown)
{
if (countdown > 0)
    recursiveFxn(countdown - 1);
else
    throw new Exception("lol.  Forced exception.");
}