欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表
最新评论

方法的终止与异常处理

创建时间:2013年01月23日 22:15  阅读次数:(5921)
分享到:
本章主要讲述了在CLR中如何进入一个方法,在结束本章之前,让我们看看方法在被调用之后是如何结束的。
正常终止与异常终止

除了进程终止、AppDomain终止和线程终止之外,方法进入后结束的方式有两种.正常终止和异常终止,如图6.14所示。CIL的ret指令可以终止每个方法的指令流,它将触发正常终止(normal termination), rer指令还可以出现在指令流的其他位置,这往往取决于c#、c++或者VB.NET中的return语句。当一个方法正常终止时,它的类型化的返回值对于调用方是可用的,并且,CLR 保证任何按引用传递的参数将会反映由方法所做的修改。

异常终止与正常终止有两点同:其一,当一个方法异常终止时,其类型化返回值对于调用方是不可用的:其二,按引用传递的参数可能受到方法体的影响。虽然在异常终止的情形下,方法调用的结果是不可用的,但还是有一个介质可以传递输出给被调用方.这个介质就是异常(exception)对象。

引发异常触发了方法的异常终止( abnormal termination)。CLR自身可以引发异常作为对异常条件的响应(例如,使用一个空引用,除以零)。应用程序代码也能通过CIL的throw指令引发异常(在C#、c++和VB.NET中是由throw语句触发的)。归根结底,无论是CLR还是应用程序抛出的异常,其异常处理的工作方式都是一样的,因此,后面的讨论重点是使用throw指令引发的异常.

throw指令需要一个异常对象的引用,该异常对象将传达异常终上的原因。异常对象是System.Exception或者其派生类型的实例。CLR(像c++与Java一样)使用异常的类型表明错误的原因,而不是使用错误代码为此,CLR定义了两个System.Exception类型的通用子类型:CLR采用System.SystemException作为基类型,用于系统级别的异常类型,CLR采用System.ApplicationExcepttion作为基类型,用于应用程序相关的异常类型。图6.15展示了一些系统级别的异常。

异常不仅带有来自方法的可替换结果或指示,而且异常的抛出将导致CLR改变正常执行的路线。尤其是,CLR将通过遍历当前执行线程的堆栈,查找合适的异常句枘。每个堆栈帧有一个异常表( exception table),标明方法的异常句柄的定位,以及它们所适用的指令范围。CLR查看指令计数,以便堆栈帧确定哪个句柄是适合的。

每种编程语言都提供了其自身的语法用于构成方法的异常表。图6.16展示了最简单的c#异常句柄,在这个例子中,divide方法在其异常表中恰好有一个入门项,受保护部分的范围为赋值语句和对b的调用。这个句柄还将延伸到对e的调用。这是一个无条件句柄,也就是说在这个方法执行时,即使在受保护体中有任何异常被抛出,该句柄代码仍会执行,这个异常也就被认为是处理了。在异常被处理以后,程序将会从调用g的指令位置继续执行。
Try-catch语句

不论异常对象的类型如何,CLR部将使用这个异常句柄。当然,你也可以给一个异常句柄增加判定(predicate),限制该句柄兼容于给定的异常类型。例如,考虑图6.17所展示的c#异常句柄。这个方法有一个带有三个人口的的异常表,对于异常表中的每个入口项,都有相同的保护范围,也就是它们都对应于同一个try块。在该表中第一个人口项将有一个基于类型的判定,假设当前的异常与FancyException不兼容,那么,该句柄将被忽略。同理,假设当前异常的类型与NormalException不兼容,那么,第二个句柄出将被忽略。
带声明的Try-catch语句

最后,异常表的第三个入口项有一个基于类型的判定,它需要异常System.Object兼容。实际上,第三个人口项成了无条件句柄。需要注意的是,CLR将按顺序遍历异常表。因此,像这样让更具体的类型句柄判定在通用句柄之前出现是很关键的。c#编泽器将实施这项检查,并报告相应的编译错误。不过,你所使用的编译器有可能不那么细致。

异常表还包含有终止句柄的入口项。当控制权离开受保护的指令范围时,终止句柄(termination handler)都将被引发。当异常导致执行跳出保护体时,CLR将执行终止句柄;当受保护的指令止常地执行完毕时,CLR仍将执行终止句柄,在c#中,你可以使用try-finally语句创建终止句柄,如图6.18所示。在这个例子中,受保护范围的指令是赋值语句和对b的调用。在该范围的指令执行后,CLR保证终止句柄语句将被执行(在这里,就是对f的调用)。如果没有异常被抛出,那么,对f的调用将在对b的调  用之后立即发生。如果方法在指令受保护范围内的执行过程中,有一个异常  被抛出了,那么,在CLR展开该方法堆栈帧之前,将会调用f方法。
带声明的Try-Finally语句

你可以为一个给定的C# try块内指定多个异常句柄,还可以在异常句柄列表之后指定一个终止句柄,如图6.19所示。这里,每个句柄(终上句柄或异常句柄)在方法的异常表中都有它自己的入口项。
Try-Catch-Finally语句

我们走到哪儿了
CLR提供了一系列的机制,用于引发方法代码的执行。这些机制都允许开发人员控制将被调用的方法,以及指定参数的方式。其中,有一些机制假定方法调用是隐式的,而另一些则使方法调用成为显式的。CLR允许开发人员基于所期望的并发特性,显式地同步或者异步地调用方法。
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 16+30=? 的结果(结果是:46)
结  果: