結構化異常處理不好嗎?什麼是處理異常的正確方法?異常處理
編輯:在.NET中使用C#的異常處理。
我通常有一組特定的異常類(DivideByZeroException,ArrayTypeMismatchException)並且沒有泛型「catch(Exception ex)」。
這個背後的思想是,我期望發生某些類型的異常,並在發生異常時定義特定的操作,並且意外的異常會升起界面(無論是Windows還是Web)。這是一個很好的做法嗎?
結構化異常處理不好嗎?什麼是處理異常的正確方法?異常處理
編輯:在.NET中使用C#的異常處理。
我通常有一組特定的異常類(DivideByZeroException,ArrayTypeMismatchException)並且沒有泛型「catch(Exception ex)」。
這個背後的思想是,我期望發生某些類型的異常,並在發生異常時定義特定的操作,並且意外的異常會升起界面(無論是Windows還是Web)。這是一個很好的做法嗎?
捕獲語句+堆棧跟蹤。在沒有打印堆棧跟蹤的情況下,如果沒有捕獲到異常,您或其他人將不得不再次檢出該代碼,並在發生錯誤並且日誌文件爲空或模糊時在Catch塊中放置堆棧跟蹤。
我不確定'結構化異常處理'是什麼意思。
在異常處理中可以做的最糟糕的事情是「吞下」異常或者靜靜地處理異常。
不這樣做:
try {
...
}
catch (Exception e) {
//TODO: handle this later
}
這是很經常做出於懶惰讓代碼編譯。如果您不知道如何處理特定級別的異常,請讓該方法拋出異常,並且至少在頂部有一個catch all handler。以某種方式提供反饋(通過GUI,頁面/電子郵件發送給支持人員,日誌文件),以便問題最終得到解決。默默地捕捉異常幾乎總是會導致稍後發生更大的問題,並且難以追蹤。
我的建議:
不要捕捉異常,除非:
捕獲在儘可能高的水平異常意味着你得到最大的調用堆棧,當你經歷的日誌,並想看看初始動作觸發的序列,這是非常有用的首先導致例外的事件。
這是一個複雜的話題......有這方面的書......但......有兩種主要的異常處理類型......內聯,其中處理潛在錯誤的代碼與方法或例程將「正常」執行的代碼以及結構化異常處理(其中代碼位於其他地方)以及基礎結構被設計爲自動處理該異常處理代碼意外事件(錯誤)發生......兩者都有優勢和劣勢。 「內聯」方法傾向於產生更加混亂的代碼(帶有錯誤代碼),難以閱讀和維護。但是,由於它不需要任何前期分析,所以它更容易生成。使用內聯錯誤處理時,您經常會看到方法返回布爾值或數字「錯誤」代碼,向調用方指明metjhod或例程是否成功。這消除了使例程「返回」有意義的業務價值或對象的「功能」語法(因爲按慣例每個函數都必須返回錯誤代碼)。使用結構化異常處理時,此問題沒有實際意義。
結構化異常處理otoh通常很難做好,因爲它需要事先分析例程或方法可能產生的錯誤以及該方法可以或應該對每個錯誤執行什麼操作if它確實發生。
有一兩件事是肯定的,不要在單一成分的兩種方法混合...
我不是一個Windows程序員,但在使用結構化異常處理處理硬件異常之類的軟件在我看來,例外意味着:
所以問題要問,IMO,主要有:
如果答案爲'是','是','否',則需要結構化的異常處理。否則,你可能可以避免它,在這種情況下,你可能想要。編寫異常安全的代碼非常棘手,所以異常保證越強大,你越能提供更好的結果。可能與SEH劃分爲零的代碼不提供不保證,或許在重新設計時可能會導致呼叫者不提供數據,但可以這樣做。但是如果一個函數由於其他原因而必須拋出異常,那麼也可能將它們丟給硬件陷阱,這可能會讓事情變得更糟。
一個值得注意的特例是內存分配。不確定.NET是否這樣做,但是如果分配的虛擬地址空間不足,則Linux分配只會失敗。物理內存在第一次使用時被提交,如果沒有足夠的硬件,會導致硬件異常。由於內存分配是假定在發生故障時拋出std :: bad_alloc,並且實現未能實現此標準的這一要求,所以可能是是因爲在某些情況下將硬件異常轉換爲軟件是正確的。但是,這種硬件異常可能會發生在意想不到的地方(包括您認爲不太合適的例程),所以仍然可能無法妥善處理,這就是爲什麼linux核心轉儲而不是拋出。在實踐中,完全初始化的任何東西都會導致其構造函數崩潰,這通常足夠接近分配,而軟件異常會變得有用。
「結構化」是什麼意思? – 2008-12-09 14:33:03
如果你提到了一種語言,這將是一件好事,所以我們可以在詳細和更好的情況下幫助你。 – GEOCHET 2008-12-09 14:33:06