异常处理,英文名为Exceptional Handling,那时年少,还记得那年一起学习过的VB6.0的时候,常常使用ONError的错误语句。与传统VB6.0中的OnError语句相比.NET平台的异常处理机制更加灵活,而且使用更加方便。是代替日渐衰落的Error Code方法的新法,提供Error Code 所未能具体的优势。异常处理巧妙又不失完美的分离了接收和处理错误代码。这个功能理清了编程者的思绪,也帮助代码增强了可读性,方便了维护者的阅读和理解。
异常处理(又称为错误处理)功能提供了处理程序运行时出现的任何意外或异常情况的方法。异常处理使用 try、catch 和 finally 关键字来尝试可能未成功的操作,处理失败,以及在事后清理资源。异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。
一、异常处理Try...Catch...Finally
在上述语句中,Try语句块通常存放的是我们需要检测可能存在异常情况的代码,也就是说如果程序正确,则执行Try语句块,Catch语句块负责捕捉到错误的代码。所以当这段代码在执行过程中产生异常,则转到Catch块中对该异常进行相应处理。最后,无论是否引发异常,Finally块中的代码最后一定会被执行。 Finaly块用于清除try块中分配的任何资源以及运行任何即使在发生异常时也必须执行的代码。Catch和Finally语句可以共同使用于一个Try块中。
简单来说,就是Try和Finally语句块是必须运行的,但是Catch语句不一定运行,如果Try块内的代码没有错误,没有抛出异常的话,Catch语句块中的代码是不运行的,而是跳过Catch块直接运行Finally块中的清理工作。反之如果遇到了异常Catch语句块中的处理工作就要进行。为什么在Finally块中进行清理工作?简单的说一个程序的异常会导致程序不能正常完成结束工作,而且在错误出现的地方跳出程序,直接执行Catch语句块中的代码,使得在程序运行时构建的对象资源不能释放,浪费了内存资源,同时也可能导致栈中数据存储的杂乱,所以无论有没有出现异常Finally块中的代码是一定会运行的。
以VB.NET版机房收费系统中的注册为例,我们要如何在代码中应用异常处理呢?
如果,我们没有写捕获异常的这个语句,该注册在D层出错了,运行结果会怎样?
- <span style="font-size:18px;"><span style="font-size:18px;"> Private Sub btnSave_Click(sender As Object,e As EventArgs) Handles btnSave.Click
- Try
- Dim RegisterManager As New BLL.RegisterManager
- Dim studentinfo As New Entity.Studentinfo
- Dim cardinfo As New Entity.Cardinfo
- Dim rechargeinfo As New Entity.Rechargeinfo
- If (RegisterManager.query(txtStudentNo.Text) Is Nothing And RegisterManager.queryCard(txtCardNo.Text) Is Nothing) Then
- studentinfo.cardNo = txtCardNo.Text
- studentinfo.studentNo = txtStudentNo.Text
- studentinfo.studentName = txtName.Text
- studentinfo.sex = cmbSex.Text
- studentinfo.department = txtDepartment.Text
- studentinfo.grade = txtGrade.Text
- studentinfo.stuclass = txtClass.Text
- studentinfo.remark = txtRemark.Text
- studentinfo.Handler = frmLogin.handler.handler
- '用户显示层没有处理人这个文本框,怎么办?数据库里面handler这个字段的信息如何获取,答案就在上面哦。
- cardinfo.cardNo = txtCardNo.Text
- cardinfo.balance = txtbalance.Text
- cardinfo.status = "使用"
- cardinfo.registerDate = CStr(Format(Now(),"yyyy-MM-dd"))
- cardinfo.registerTime = CStr(Format(Now(),"HH:mm:ss"))
- cardinfo.handler = frmLogin.handler.handler
- cardinfo.ischeck = "未结账"
- rechargeinfo.cardNo = txtCardNo.Text
- rechargeinfo.rechargeAmount = txtbalance.Text
- rechargeinfo.rechargeDate = CStr(Format(Now(),"yyyy-MM-dd"))
- rechargeinfo.time = CStr(Format(Now(),"HH:mm:ss"))
- rechargeinfo.userID = frmLogin.handler.handler
- RegisterManager.insert(studentinfo)
- RegisterManager.insertCard(cardinfo)
- RegisterManager.insertRecharge(rechargeinfo)
- MsgBox("用户注册成功")
- End If
- Catch ex As Exception
- MessageBox.Show(ex.Message.ToString())
- End Try
- End Sub</span></span>
正如上图所示,她会直接跳到有错误的地方,但是如果在程序里面写了Try Catch,又会发生怎样的奇迹呢?
两种不同的报错方式,第二种给人的感觉更加直观,帮助我们理清了思绪,增强了代码可读性,方便维护者的阅读和理解。
二、 抛出异常
当程序出现异常状况时会导致系统提前跳出该程序,运用Catch捕捉异常,可使我们继续执行Catch的内容。try...catch 捕获的是系统自行检测出来的错误。如果我们需要自定义一些错误,例如检测到了卡号不存在等错误的时候,我们可以使用Throw 关键字来在程序中抛出异常。
Throw关键字通常用于方法体中,并且抛出一个异常对象,如果一个方法没有捕获可能引发的异常,调用该方法的其他方法应该捕获并处理异常。程序在执行到throw语句时立即终止,它后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法的声明中指明要抛出的异常;如果要捕捉throw抛出的异常,则必须使用try-catch语句。例如,为了保证逻辑的正确,在程序中判断如果有违逻辑的部分可以抛出一个异常,如:任何数都不能除0,如果0作为除数的话就要抛出一个异常,throw new exception("0不能作为除数!")
代码如下:
使用异常处理,可以使大多数的正常代码与少数异常处理的分离,其次错误分类统一处理,最后通知使用者具体发生了什么错误。机房收费系统,未完,待续......
- <span style="font-size:18px;">Private Sub butnTest_Click(sender As Object,e As EventArgs) Handles Button1.Click
- Try
- Dim g As Integer =3
- Dim h As Integer =0
- TextBox1.Text = GetTry(g,h)
- Catch ex As Exception
- MsgBox("除数不能为0",vbOKOnly + vbInformation,"系统消息")
- Finally
- MsgBox("结束")
- End Try
- End Sub
- Private Function GetTry(ByVal a As Integer,b As Integer) As Integer
- If b = 0 Then
- Dim excOurOwnException As New ArgumentException("除数不能为0") '抛出异常
- Throw excOurOwnException
- End If
- End Function </span>