在遇到 .NET 中的一些 StackOverflowExceptions 后,我注意到它们完全绕过了 .NET 提供的未处理的异常处理程序(Application.ThreadException / AppDomain.UnhandledException)。
这是非常令人不安的,因为我们在这些异常处理程序中有关键的清理代码。
有什么办法可以克服这个问题吗?
所谓的“异步异常”分为三种。它们是 ThreadAbortException、OutOfMemoryException 和提到的 StackOverflowException。代码中的任何指令都允许发生这些异常。
而且,还有一种方法可以克服它们:
最简单的是 ThreadAbortException。当当前代码在finally块中执行时。 ThreadAbortExceptions 有点“移动”到finally 块的末尾。因此,finally 块中的所有内容都不能被 ThreadAbortException 中止。
为了避免 OutOfMemoryException,您只有一种可能性:不要在堆上分配任何内容。这意味着您不允许创建任何新的引用类型。
要克服 StackOverflowException,您需要框架的一些帮助。这种帮助体现在约束执行区域中。所需的堆栈已分配before实际代码被执行,此外还确保代码已经过 JIT 编译,因此可供执行。
在约束执行区域中有三种形式执行代码(复制自BCL 团队博客 http://blogs.msdn.com/bclteam/archive/2005/06/14/429181.aspx):
- ExecuteCodeWithGuaranteedCleanup,try/finally 的堆栈溢出安全形式。
- try/finally 块前面紧跟着对 RuntimeHelpers.PrepareConstrainedRegions 的调用。 try 块不受约束,但该 try 的所有 catch、finally 和错误块都是受约束的。
- As a critical finalizer - any subclass of CriticalFinalizerObject has a finalizer that is eagerly prepared before an instance of the object is allocated.
- 一个特殊情况是 SafeHandle 的 ReleaseHandle 方法,这是一个在分配子类之前急切准备的虚拟方法,并从 SafeHandle 的关键终结器中调用。
您可以在这些博客文章中找到更多信息:
约束执行区域和其他勘误表 [Brian Grunmeeyer] http://blogs.msdn.com/bclteam/archive/2005/06/14/429181.aspx在 BCL 团队博客上。
乔·达菲 (Joe Duffy) 的博客关于原子性和异步异常失败 http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=c1898a31-a0aa-40af-871c-7847d98f1641他对 .net Framework 中的异步异常和稳健性进行了很好的概述。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)