Try...Catch...Finally 和Throw 叙述

发表于:2007-07-14来源:作者:点击数: 标签:
介绍完了On Error 叙述后,相信大家对于错误处理的方式及流程应该有基础的认识了。接着我们要来介绍.NET 架构里最新的错误处理方式Try...Catch。我们前面提到On Error 虽然简单但是不够结构化,因此.NET 便加入了Try...Catch 的除错方式,使我们能够更有效率


    介绍完了On Error 叙述后,相信大家对于错误处理的方式及流程应该有基础的认识了。接着我们要来介绍.NET 架构里最新的错误处理方式Try...Catch。我们前面提到On Error 虽然简单但是不够结构化,因此.NET 便加入了Try...Catch 的除错方式,使我们能够更有效率的撰写错误处理法则。

例外(Exception)
    错误被称为例外(Exception),而例外也是对象;它和Err 对象不一样,不同的例外被做成不同的对象。例如将非数值型态的数据以型态转换函数处理时,会发生FormatException 型态的例外;而提供这个例外信息的是FormatException 对象。

Try...Catch
Try...Catch 的概念基本上和On Error 叙述一样,它也是当发生错误时就跳到例外处理程序中,其结构如下所示:

Try
程序执行的区块
Catch 变量As 例外对象
例外处理程序的区块
End Try

我们可以针对不同的例外来建构不同的例外处理程序,例如:

Try
程序代码
Catch 变量As 例外对象
例外处理程序代码
Catch 变量As 例外对象
例外处理程序代码
[Finally]
例外处理程序代码
End Try

下列范例将On Error 错误捕捉改成Try...Catch 处理,我们一样只要输入非数值型态的内容至TextBox 中即可引法错误:

<Html>
<Form Runat="Server">
<ASP:TextBox Id="Text1" Runat="Server"/>X
<ASP:TextBox Id="Text2" Runat="Server"/>
<ASP:Button Id="Button1" Text="=" OnClick="Button1_Click"
Runat="Server"/>
<ASP:Label Id="Label1" Runat="Server"/><p>
<ASP:Label Id="Label2" Runat="Server"/>
</Form>
<Script Language="VB" Runat="Server">
Sub Page_Load(Sender As Object,e As Eventargs)
Label1.Text=""
Label2.Text=""
End Sub
Sub Button1_Click(Sender As Object,e As EventArgs)
Try
Label1.Text=CInt(Text1.Text)/Cint(Text2.Text)
Catch ex as FormatException
Label2.Text="两边都必须输入数字"
End Try
End Sub
</Script>
</Html>


    由于将非数值型态的内容传入CInt 函数中态引发了FormatException 类型的错误,因此就跳到Catch 区块来处理例外。由于例外对象全部都是从Exception 对象继承下来的,因此在使用多个Catch 时要注意顺序。例如下面程序代码片段,我们若把Exception 类别的对象放在FormatException 类别对象之前,则侦测FormatException 类型的例外处理将不会被执行:

Try
引发例外的程序代码
Catch err1 As Exception
例外处理的程序代码
Catch err2 As FormatException
例外处理的程序代码
End Try


Finally
    Finally 区块不管有没有发生例外都会执行,我们可以使用Finally 区块来做一些最后的处理。下列范例当我们按下Button1 程序执行到Try 区块,无论例外有无发生都会执行Finally 区块的中的程序代码:

<Html>
<Form Runat="Server">
<ASP:TextBox Id="Text1" Runat="Server"/>X
<ASP:TextBox Id="Text2" Runat="Server"/>
<ASP:Button Id="Button1" Text="=" OnClick="Button1_Click"
Runat="Server"/>
<ASP:Label Id="Label1" Runat="Server"/><p>
</Form>
<Script Language="VB" Runat="Server">
Sub Page_Load(Sender As Object,e As Eventargs)
Label1.Text=""
Label2.Text=""
End Sub
Sub Button1_Click(Sender As Object,e As EventArgs)
Try
Response.Write("Try 区块<Br>")
Label1.Text=Cint(Text1.Text)/Cint(Text2.Text)
Catch ex As FormatException
Response.Write("Catch 区块<Br>")
Finally
Response.Write("Finally 区块")
End Try
End Sub
</Script>
</Html>



没有发生例外时

发生例外时

Throw
    在On Error 结构中我们可以使用Err 对象的Raise 方法来自行引发一个例外,而ASP.NET 新的例外处理机制中也提供了Throw 叙述,让我们引发一个自订的错误叙述;其使用语法如下:

Throw New 例外对象

下列范例中我们自行丢出一个Exception 型别的例外,然后在Catch 区块中印出Exception 类别对象的例外说明:

<Html>
<Form Runat="Server">
<ASP:Button Id="Button1" Text="产生例外" OnClick="Button1_Click"
Runat="Server" />
</Form>
<Script Language="VB" Runat="Server">
Sub Button1_Click(Sender As Object,e As Eventargs)
Try
Response.Write("自行丢出一个Exception 例外<Br>")
Throw New Exception
Catch ex As Exception
Response.Write(ex.ToString())
End Try
End Sub
</Script>
</Html>



     Try....Catch 的结构化使得我们的例外处理变的相当有效率,我们可以在程序代码中使用Try....Catch 结构来处里我们的例外,不用担心程序的执行流程被改变。使用Try....Catch 要注意不破坏原有的程序代码结构,例如下列程序代码片段是错误的示范:

Try
For shtI=0 To 9
Response.Write(shtI)
Catch ex As Exception
...
Next

巢状的Try...Catch
我们可以在Catch 区块或Finally 区块中再使用Try....Catch 叙述,如下列范例所示:

<Html>
<Form Runat="Server">
<ASP:Button Id="Button1" Text="产生例外" OnClick="Button1_Click"
Runat="Server"/>
</Form>
<Script Language="VB" Runat="Server">
Sub Button1_Click(Sender As Object,e As Eventargs)
Try
Response.Write("自行丢出一个Exception 例外<P>")
Throw New Exception
Catch err As Exception
Try
Response.Write(err.ToString() & "<P>")
Response.Write("再产生一个例外<P>")
Throw New IndexOutOfRangeException()
Catch err1 As IndexOutOfRangeException
Response.Write(err1.ToString())
End Try
End Try
End Sub
</Script>
</Html>

原文转自:http://www.ltesting.net