文档库

最新最全的文档下载
当前位置:文档库 > NET异常处理机制

NET异常处理机制

.NET学习之.NET Framework的异常处理机制

几番决心之后,决定写这个.NET学习系列,算是对平时积累下来的知识点一个回顾和总结,为自己建立起一个系统的知识体系打好基础,也顺便提高一下自己的语言组织能力。好了,废话也不多说,入正题。

本章主要分下面几个方面来介绍.NET Framework的异常处理机制。

一、什么是异常?

二、异常是怎么产生的?

三、.NET Framework是如何来处理异常的?

四、异常处理实例。

一、什么是异常?

异常(exception)是程序在运行时所产生的一种事件,这种事件往往是非预期的,并且会打断程序的正常运行流程。我们应当注意异常与错误(error)之间的区别,这里有个比较正式的解释,“一个异常是在一个程序执行过程中出现的一个事件,它中断了正常指令的运行--Mary Campione 《The Java Tutorial》”,而错误是“偏离了可接受的代码行为的一个动作或一个实例 --From American Heritage Dictionary”.有点晦涩难懂吧?我认为错误与异常是存在交集的,不可能完全区分,狭义的异常就是错误。

二、异常是怎么产生的?

不管你的编程能力有多高,仍然可能面对很多意料之外的情况,例如,你的程序需要读写客户机上的某一个文件但并没有获得对该文件的写权限,在进行同服务器之间通信时网络突然中断,这些意料之外的情况都可能引发程序的异常。

三、.NET Framework是如何来处理异常的?

在.NET框架中,当出现某个异常时,会创建一个异常对象。这个异常对象包含了有助于跟踪问题的相关信息。针对于普遍性的异常情况,.NET提供了许多预定义的异常类。同时,也允许我们通过创建自己的异常类来跟踪特定的应用程序异常。

首先,我们来看.NET的异常类层次结构。

在.NET中,所有异常类都是派生于Exception基类。当然,Exception基类是从Object 类派生出来的。

在该层次结构中,注意其中有两个重要的类,System.SystemException类以及System.ApplicationException类。SystemException类通常是由.NET运行库生成的,面向普遍的情况,可以由几乎所有的应用程序生成。而ApplicationException 类则是用于自定义的异常基类。

然后我们来看看.NET Framework异常处理的一般流程:

一般来说,为了在.NET Framework中处理可能的错误,会采用try…catch…finally 这样的代码结构,其中,try块包含了程序的正常操作部分,但可能会遇到某些异常,catch 块包含的代码用于处理在try中产生的相应的异常,而finally块主要用于清理资源(例如关闭在try块中打开的数据库连接)或执行要在try块或catch块末尾执行的其他操作,注意,无论是否产生异常,finally块中的代码都是要执行的。在该结构中,finally 代码块是可选的。所以.NET Framework异常处理的一般流程是:

(1)程序流进入try块。

(2)如果在try块中没有异常产生(抛出),那么程序将跳过catch块而进入到finally块。但如果在try中程序流检测到一个错误,那么程序流就会进入到catch块中。

(3)在catch块中处理try中产生的相应错误,注意这里的相应,一般来说,一个try 块可以对应多个catch块,一个catch块用于捕获一个特定的错误,如果try块

产生(抛出)的错误并不是catch块所处理的特定的错误,那么该错误将不会在该

catch块中得到处理。这里留一个疑问:那么未被该catch捕获的异常应该在哪

里得到处理呢?

(4)在catch块执行完后,程序流进入finally块。

(5)执行finally块中的代码。

也许,在上述的流程中,很多异常都能够得到处理,但是,我们仍然需要考虑复杂的特殊环境中的异常处理,就比如说我们刚才提出的疑问:未被该catch捕获的异常应该在哪里得到处理呢?在回答这个问题之前,我们先来看异常处理代码块的嵌套机制,有下面的代码:try

{

//block A

try

{

//block B

}

catch

{

//block C

}

finally

{

//block D

}

}

catch

{

//block E

}

finally

{

//block F

}

在上面的代码结构中,如果按照我们之前的一般流程来处理是可以的,在A块中抛出的异常由E块捕获处理,在B块中跑出的异常由C块捕获处理,但是我们考虑一些特殊的情况,第一种情况:

如果在C块或E块中也产生了异常,那么该异常将如何被处理?

第二种情况:

如果A块或B块中抛出的异常不能在相应的E块或C块中被捕获,那么该异常应当如何处理?

我们先来回答第一种情况的问题:

如果在外层的catch块(block E)中产生了异常,那么它将由.NET Framework运行库捕获,实际上,.NET Framework运行库是把整个程序都放在另一个更大的try块中,这个try块有一个catch处理程序,可以捕获任何类型的异常。如果在代码中没有处理发生的异常,那么.NET Framework运行库捕获到该异常,然后中断程序的执行,并给出

由.NET Framework运行库检索到的异常信息。

有了上一个答案,那么下面的分析就很显然了,如果在内层catch块(block E)中产生了异常,那么仍然按照我们一般的流程,执行内层finally块(block D)中的代码,然后处理程序在外层的catch块中(E块)中搜索是否有对应的处理代码。如果有,则在外层的catch块中得到处理,如果没有,则由.NET Framework运行库捕获处理。第二种情况分析过程也是一样。

因此,我们可以总结出.NET Framework对异常处理的方式,首先,内层try抛出的异常如果在内层的catch块中未得到处理,那么在执行完内层finally块后,将转到次外一层的catch块中,以此类推,直到所有的catch块都不能处理该异常时,则由.NET Framework运行库捕获并处理。