异常处理的内部实现

本文关键字:实现 内部 异常处理 | 更新日期: 2023-09-27 17:50:29

今天,当我写这样一段代码:

try
{
   ...
}
catch (Exception e)
{
   ...
}

我突然意识到

catch (Exception e)
{
  ...
}

语句非常像函数声明。我模糊地记得异常处理涉及某种堆栈遍历/操作。

那么,上面的异常处理代码被编译成什么呢?我感觉上面的代码只是一种特殊/方便的语法,以简化我们的编码,但实际上,也许我们的代码被包装成一个自动生成的异常处理函数?我希望我说得够清楚了。

异常处理的内部实现

幸运的是,CLR架构师Chris Brumme写了一篇很长的解释,解释了CLR中的异常处理是如何工作的。现在,这是八年前写的,一些细节今天略有不同,但这至少应该给你一个良好的开端。

http://blogs.msdn.com/b/cbrumme/archive/2003/10/01/51524.aspx

这是一个很好的开始:http://msdn.microsoft.com/en-us/library/5b2yeyab.aspx#how_the_runtime_manages_exceptions

基本上,它们有点像函数,但不是真的。它们本身不被调用,它们没有单独的堆栈帧(或单独的堆栈,就此而言),而是使用当前函数的堆栈帧。这就是为什么你可以访问本地变量。

如果你想看到它编译成什么,你可以使用ILDasm.exe来反编译一个有异常块的程序集(所以做一个示例程序并反编译它)。或者,使用RedGate的Reflector来获得更好的反编译体验。

如果IL不够,您可以在Visual Studio中以调试模式运行程序,在方法中设置断点,然后在遇到该断点时,从debug菜单中打开反汇编选项卡/窗口,从而获得生成的程序集。