任何完美的應用程序和技術高明的程序員,都不可能是絕對不出差錯的。與其追求完美無錯的代碼,還不如將程序中可能預知的異常在發布前進行很好的處理,可能是最有價值的。那么,C#是如何處理異常的呢?首先,我們從最普通的異常說起:
使用try-catch-finally塊捕獲異常,基本格式如下:
1 try 2 { 3 //獲取並使用資源,可能出現異常 4 } 5 catch(DivideByZeroException de) 6 { 7 } 8 catch(ArithmeticException ae) 9 { 10 } 11 catch(Exception e) 12 { 13 //捕獲並處理異常,當出現多個異常且異常類之間有繼承關系(DivideByZeroException==>ArithmeticException==>Exception), 14 //捕獲順序是子類在前,基類在后 15 } 16 finally 17 { 18 //無論什么情況(即使在catch塊中return)下,都會執行該塊的代碼(如:關閉文件) 19 //另外需要說明的是,在finally塊中使用任何break、continue、return退出都是非法的。 20 }
ASP.NET異常處理
除了以上的try-catch-finally的處理方式外,還有三種方式來捕獲異常:
1. 頁面級錯誤處理(通過Page_Error事件)
protected void Page_Error(object sender, EventArgs e) { string errorMsg = String.Empty; Exception currentError = Server.GetLastError(); errorMsg += "系統發生錯誤:<br/>"; errorMsg += "錯誤地址:" + Request.Url + "<br/>"; errorMsg += "錯誤信息:" + currentError.Message + "<br/>"; Response.Write(errorMsg); Server.ClearError();//清除異常(否則將引發全局的Application_Error事件) }
2. 應用程序級(global.asax)錯誤處理(通過Application_Error事件)
protected void Application_Error(object sender, EventArgs e) { Exception ex = Server.GetLastError(); Exception iex = ex.InnerException; string errorMsg = String.Empty; string particular = String.Empty; if (iex != null) { errorMsg = iex.Message; particular = iex.StackTrace; } else { errorMsg = ex.Message; particular = ex.StackTrace; } //AddLog(errorMsg, particular); Server.ClearError();//處理完及時清理異常 }
3. 應用程序配置(web.config)
<system.web> <!--mode有三種值:On,Off,RemoteOnly,defaultRedirect出現錯誤重定向的URL--> <customErrors mode="On" defaultRedirect="ErrorPage.htm"> <!--statusCode錯誤狀態碼,redirect錯誤重定向的URL--> <error statusCode="403" redirect="NoAccess.htm"/> <error statusCode="404" redirect="FileNoFound.htm"/> </customErrors> </system.web>
WinForm應用程序異常處理
在WinForm的應用程序中,除了采用try-catch-finally的方式外,如何實現全局的異常處理呢?因為不具有Application_Error事件,但可以通過委托的方式來實現。
internal class ThreadExceptionHandler { //實現錯誤異常事件 public void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { try { //如果用戶單擊"Abort"則退出應用程序 DialogResult result = ShowThreadExceptionDialog(e.Exception); if (result == DialogResult.Abort) { Application.Exit(); } } catch { try { MessageBox.Show("嚴重錯誤", "嚴重錯誤", MessageBoxButtons.OK, MessageBoxIcon.Stop); } finally { Application.Exit(); } } } private DialogResult ShowThreadExceptionDialog(Exception e) { string errorMsg = "錯誤信息:\t\t" + e.Message + "\t\t" + e.GetType() + "\t\t" + e.StackTrace; return MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop); } } static class Program { ///<summary> /// The main entry point for the application. ///</summary> [STAThread] static void Main() { ThreadExceptionHandler handler = new ThreadExceptionHandler(); Application.ThreadException += new ThreadExceptionEventHandler(handler.Application_ThreadException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new frmEvent()); } } public partial class frmEvent : Form { private void btnException_Click(object sender, EventArgs e) { throw new InvalidOperationException("無效的操作異常!"); } }