在.NET中遇到一些StackOverflowExceptions后,我注意到它们完全绕过.NET提供的未处理的异常处理程序(Application.ThreadException / AppDomain.UnhandledException)。 这非常令人不安,因为我们在这些异常处理程序中有关键的清理代码。
有没有办法克服这个问题?
答案 0 :(得分:25)
有三种所谓的“异步异常”。这是ThreadAbortException,OutOfMemoryException和提到的StackOverflowException。允许在代码中的任何指令处发生这些异常。
而且,还有一种方法可以克服它们:
最简单的是ThreadAbortException。当前代码在finally块中执行时。 ThreadAbortExceptions有点“移动”到finally块的末尾。因此,最终块中的所有内容都不能被ThreadAbortException中止。
为避免OutOfMemoryException,您只有一种可能性:不要在堆上分配任何内容。这意味着您不能创建任何新的引用类型。
要克服StackOverflowException,您需要Framework的一些帮助。这种帮助体现在约束执行区域中。在执行实际代码之前,分配了所需的堆栈,并且还确保代码已经过JIT编译,因此可以执行。
在Constrained Execution Regions中执行代码有三种形式(从BCL Team Blog复制):
您可以在以下博文中找到更多信息:
Constrained Execution Regions and other errata [Brian Grunkemeyer]在BCL团队博客上。
Joe Duffy关于Atomicity and asynchronous exception failures的博客,他非常了解.net框架中的异步异常和健壮性。
答案 1 :(得分:18)
不是真的;在CLR本身内发生堆栈溢出或内存不足异常意味着出现了严重错误(当我成为笨蛋并创建递归属性时,我通常会得到它)。
当发生这种状态时,CLR无法分配新的函数调用或内存以使其能够调用异常处理程序;这是“我们必须停止现在”的情景。
但是,如果您自己抛出异常,则会调用异常处理程序。
答案 2 :(得分:1)
stackoverflow不是你可以恢复的东西,因为它甚至不能分配更多的堆栈内存来调用你的异常处理程序。
你唯一可以做的就是追查原因并防止它发生(例如,对于递归,并且不在堆栈上分配大对象)。
答案 3 :(得分:1)
blowdart将它钉在上面。 Dumbass递归财产,因为他喜欢称之为。打包代码真的只是一个问题。
private Thing _myThing = null;
Public Thing MyThing
{
get{
return this.MyThing;}
set{
this.MyThing = value;}
}