当前位置:  开发笔记 > 程序员 > 正文

.NET中的StackOverflowException

如何解决《.NET中的StackOverflowException》经验,为你挑选了2个好方法。

在.NET中遇到一些StackOverflowExceptions之后,我注意到它们完全绕过了.NET提供的未处理的异常处理程序(Application.ThreadException/AppDomain.UnhandledException).这非常令人不安,因为我们在这些异常处理程序中有关键的清理代码.

有没有办法克服这个问题?



1> Thomas Danec..:

有三种所谓的"异步异常".这是ThreadAbortException,OutOfMemoryException和提到的StackOverflowException.允许在代码中的任何指令处发生这些异常.

并且,还有一种方法可以克服它们:

最简单的是ThreadAbortException.当前代码在finally块中执行时.ThreadAbortExceptions有点"移动"到finally块的末尾.因此,最终块中的所有内容都不能被ThreadAbortException中止.

要避免OutOfMemoryException,您只有一种可能性:不要在堆上分配任何内容.这意味着您不能创建任何新的引用类型.

要克服StackOverflowException,您需要Framework的一些帮助.这种帮助体现在约束执行区域中.执行实际代码之前分配所需的堆栈,并且还确保代码已经JIT编译,因此可以执行.

在Constrained Execution Regions中执行代码有三种形式(从BCL团队博客复制):

ExecuteCodeWithGuaranteedCleanup,一个try/finally的堆栈溢出安全形式.

try/finally块之后立即调用RuntimeHelpers.PrepareConstrainedRegions.try块不受约束,但是所有catch,最后和try块的故障块都是.

作为一个关键的终结器 - CriticalFinalizerObject的任何子类都有一个终结器,它在分配对象的实例之前急切地准备好.

一个特例是SafeHandle的ReleaseHandle方法,一种在分配子类之前急切准备的虚方法,并从SafeHandle的关键终结器调用.

您可以在这些博文中找到更多信息:

受约束的执行区域和其他勘误[Brian Grunkemeyer]在BCL团队博客.

Joe Duffy关于Atomicity和异步异常失败的Weblog ,他非常了解.net Framework中的异步异常和健壮性.



2> blowdart..:

并不是的; 在CLR本身内发生堆栈溢出或内存不足异常意味着出现了严重错误(当我成为笨蛋并创建递归属性时,我通常会得到它).

当这种状态发生时,CLR无法分配新的函数调用或内存以使其能够调用异常处理程序; 这是一个"我们必须停止现在 "的情景.

但是,如果您自己抛出异常,则会调用异常处理程序.


好吧,我确实得到了这个想法......有点......在单线程环境中.但是,嘿,我们可以创建多个线程,不是吗?而且每个线程都有一个单独的堆栈,不是吗?那么为什么只有一个线程耗尽堆栈时终止整个过程?
推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有