在過去ASP時代,程式碼中只有On Error可用來捕捉或處理錯誤,而ASP.NET中,除了On Error可用之外,還可以利用Try …End Try來進行錯誤處理。
        『Try…End Try』這個新玩意兒,看起來好像很有學問的樣子,其實用起來相當的簡單,基本的指令架構如下:
Try   [ tryStatements ][ Catch [ exception [ As type ] ] [ When expression ]    [ catchStatements ] ][ Exit Try ]...[ Finally   [ finallyStatements ] ]End Try  | 
        上面是『Try…Catch…Finally』在.NET Framework中完整的定義,對於程式設計師,它的內涵就是:
Try    可能發生錯誤的程式 [ Catch [ exception [ As type ] ] [ When expression ]     發生錯誤時,要執行的指令 [ Exit Try ]若下了Exit Try 指令,則跳出Try…End Try結構 [ Catch [ exception [ As type ] ] [ When expression ]     Catch 可以有很多個,程式會依照 When 後面的expression來決定執行哪一個Catch敘述 [ Finally    只要一進入Try敘述中,不管有沒有錯誤或從Try敘述中的哪一部份離開都執行的程式 End Try  | 
底下是實例:
Public Sub TryExample()    Dim x As Integer = 5   '定義兩個整數    Dim y As Integer = 0 Try   ' 進入Try結構,從這裡開始捕捉錯誤      x =x/ y   '發生錯誤→除以零 Catch ex As Exception When y = 0   '當錯誤產生時,若Y=0就執行這段錯誤處理程式       resp(“發生錯誤,除以零!!!”)    Finally      Beep()   '只要進入錯誤處理程序,完成後就Beep一聲    End Try End Sub  | 
        這樣的錯誤處理結構,比起過去的On Error 看似複雜許多,但是程式設計上卻較結構化,程式設計師不再需要因為On Error Goto敘述Goto來Goto去,造成閱讀和撰寫的困擾而傷腦筋。
        我們看一個實例,請開啟一個Web From,在上面佈置兩個TextBox、一個Button和一個Label:
        並在Run這個按鈕的Click事件裡,撰寫底下的程式碼:
完整範例請參考Chapter02\TryError\Default.aspx  | 
0001:    Private Sub Run_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Run.Click 0002:        Dim n1, n2 As Single 0003: 0004:        Try '開始Try...End Try 迴圈 0005:            '這裡是可能發生錯誤的(想要捕捉錯誤的)敘述 0006:            n1 = Me.NumA.Text / Me.NumB.Text 0007:            n2 = Me.NumB.Text / Me.NumA.Text 0008: 0009:        Catch ex As Exception When Me.NumB.Text = 0 0010:            '當發生錯誤,且NumB.Text=0時執行... 0011:            Me.result.Text += "<br>-->發生錯誤(B):" & ex.Message 0012: 0013:        Catch ex As Exception When Me.NumA.Text = 0 0014:            '當發生錯誤,且NumA.Text=0時執行... 0015:            Me.result.Text += "<br>-->發生錯誤(A):" & ex.Message 0016: 0017:        Catch ex As Exception 0018:            '當發生錯誤時執行... 0019:            Me.result.Text += "<br>-->發生錯誤:" & ex.Message 0020: 0021:        Finally '只要進入錯誤迴圈即執行 0022:            Me.result.Text += "<br>-->執行過 Finally..." 0023: 0024:        End Try '開始Try...End Try 迴圈 0025: 0026:        Me.result.Text += "<br>-->n1 (A/B):" & n1 0027:        Me.result.Text += "<br>-->n2 (B/A):" & n2 0028:    End Sub  | 
        從第4到24行是一段完整的Try…End Try迴圈,第5到7行是我們想要捕捉的錯誤可能發生的位置(我們判斷有可能使用者輸入0,導致除以零錯誤),當錯誤發生在這裡時,就會被Try…End Try迴圈捕捉。
        9到11、13到15、17到19都是當錯誤發生時,要處理的對應程序,我們看第9行的例子:
Catch ex As Exception When Me.NumB.Text = 0  | 
        當錯誤發生,且『Me.NumB.Text = 0』時,則執行9到11行的程式。(很有趣的事情是,在.NET Framework上,這段程式永遠不會被執行,因為居然沒有除以零錯誤!很怪?待會解釋…)
        如果發生錯誤時,不是第9和13行的『Catch ex As Exception When Me.NumB.Text = 0』和『Catch ex As Exception When Me.NumA.Text = 0』,則會處理第17行『Catch ex As Exception』以後的敘述。
        『Exception』傳回錯誤處理程序的物件,ex.Message 傳回錯誤訊息,而ex.Source則傳回發生錯誤的程式碼來源。
        我們實際看執行例子,首先,在欄位中輸入7和3,這個例子比較沒有爭議,計算結果直接顯示出來,整個過程中沒有發生錯誤,因此不會有捕捉錯誤的訊息,但是請注意,依舊會執行到程式中的『Finally』部分:
        但是當我們把A和B改成底下這樣,錯誤就發生了:
        這時候,由於輸入的B是『DEF』,並非一個數字,因此會被程式第17行的『Catch ex As Exception』例外處理程序所捕捉到,然後執行第18行顯示出錯誤訊息(從字串 "DEF" 轉換為型別 'Double' 是無效的)與發生位置(Microsoft.VisualBasic)。
        請注意,當您輸入的值是英文字的時候,並不會被第9或13行的例外處理程序捕捉到,因為,當時的數值並非0,而是文字,所以處理的程序是第17行,然而,當我們真的輸入0時,又會如何呢?
        這就是剛才提過挺有趣的部分,在.NET Framework中,居然不會有『除以零錯誤』,請注意,當我們把3/0時,結果並不會發生錯誤,因此第9、13、17行的錯誤處理程序完全派不上用場,只有第21行的『Finally』依舊老實的被執行了(記得嗎?只要進入錯誤處理程序,即使不發生錯誤,依舊會執行Finally後的敘述)。
        在.NET Framework中,3/0的結果是→『正無窮大』!!! 
『正無窮大』實際在記憶體內的表示為『1.#INF』,『正無窮大』為呼叫ToString傳回的結果。 『負無窮大』實際在記憶體內的表示為『-1.#INF』,『負無窮大』為呼叫ToString傳回的結果。  | 
        好樣的,.NET Framework還真是神奇,我們試試看另外一個狀況,我們把0除以0,看看結果如何?
        程式照常執行,但是顯示出來的結果是『不是一個數字』。您會發現與傳統的程式設計有點不同,.NET Framework中捕捉了除以零的狀況(應該說是允許其發生),而將其賦予可呈現的值。
『不是一個數字』實際在記憶體內的表示為『-1.#IND』,『不是一個數字』為呼叫ToString傳回的結果。  | 
        從上面這個例子,可以看到Try…End Try結構的用法,在每個Try…End Try之中,一定要有至少一個Catch敘述,否則會發生錯誤,而Finally則不一定需要,另外Try…End Try敘述不可與On Error敘述同時存在,儘管Visual Basic.NET對這兩個敘述都支援。





沒有留言:
張貼留言