異常處理,英文名為Exceptional Handling, 那時年少,還記得那年一起學習過的VB6.0的時候,常常使用ONError的錯誤語句。與傳統VB6.0中的OnError語句相比.NET平台的異常處理機制更加靈活,而且使用更加友善。是代替日漸衰落的Error Code方法的新法,提供Error Code 所未能具體的優勢。異常處理巧妙又不失完美的分離了接收和處理錯誤代碼。這個功能理清了程式設計者的思緒,也幫助代碼增強了可讀性,友善了維護者的閱讀和了解。
異常處理(又稱為錯誤處理)功能提供了處理程式運作時出現的任何意外或異常情況的方法。異常處理使用 try、catch 和 finally 關鍵字來嘗試可能未成功的操作,處理失敗,以及在事後清理資源。異常處理通常是防止未知錯誤産生所采取的處理措施。異常處理的好處是你不用再絞盡腦汁去考慮各種錯誤,這為處理某一類錯誤提供了一個很有效的方法,使程式設計效率大大提高。
一、異常處理Try...Catch...Finally
<span style="font-size:18px;"><span style="font-size:18px;"> Try
'程式代碼
Catch
'處理異常的代碼
Finally
'清理工作
End Try</span></span>
在上述語句中,Try語句塊通常存放的是我們需要檢測可能存在異常情況的代碼,也就是說如果程式正确,則執行Try語句塊,Catch語句塊負責捕捉到錯誤的代碼。是以當這段代碼在執行過程中産生異常,則轉到Catch塊中對該異常進行相應處理。最後,無論是否引發異常,Finally塊中的代碼最後一定會被執行。 Finaly塊用于清除try塊中配置設定的任何資源以及運作任何即使在發生異常時也必須執行的代碼。Catch和Finally語句可以共同使用于一個Try塊中。
簡單來說,就是Try和Finally語句塊是必須運作的,但是Catch語句不一定運作,如果Try塊内的代碼沒有錯誤,沒有抛出異常的話,Catch語句塊中的代碼是不運作的,而是跳過Catch塊直接運作Finally塊中的清理工作。反之如果遇到了異常Catch語句塊中的處理工作就要進行。為什麼在Finally塊中進行清理工作?簡單的說一個程式的異常會導緻程式不能正常完成結束工作,而且在錯誤出現的地方跳出程式,直接執行Catch語句塊中的代碼,使得在程式運作時建構的對象資源不能釋放,浪費了記憶體資源,同時也可能導緻棧中資料存儲的雜亂,是以無論有沒有出現異常Finally塊中的代碼是一定會運作的。
以VB.NET版機房收費系統中的注冊為例,我們要如何在代碼中應用異常處理呢?
<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>
如果,我們沒有寫捕獲異常的這個語句,該注冊在D層出錯了,運作結果會怎樣?

正如上圖所示,她會直接跳到有錯誤的地方,但是如果在程式裡面寫了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>
使用異常處理,可以使大多數的正常代碼與少數異常處理的分離,其次錯誤分類統一處理,最後通知使用者具體發生了什麼錯誤。機房收費系統,未完,待續......