一、程序中使用try catch
對於預知會發生異常的代碼段使用try catch主動捕獲異常,適用於提示給用戶或跳轉到錯誤頁面,或者經過其它方式處理異常(日誌、通知等)。web
int i = 10; int j = 0; try { Label1.Text = (i / j).ToString(); } catch (Exception ex) { // 這裏處理異常:Redirect、Transfer、Log、Notice等 Console.WriteLine("Page:" + ex.Message); }
二、Global中使用Application_Errorapp
若是異常在程序中沒有被處理(如沒有try catch),則異常的處理會流轉到這個方法,這裏邊能夠對異常進行處理。可是此方式不能捕捉子線程中的異常。asp.net
int i = 10; int j = 0; Label2.Text = (i / j).ToString();
void Application_Error(object sender, EventArgs e) { // 在出現未處理的錯誤時運行的代碼 Server.Transfer("ErrorPage.aspx"); }
string message = HttpContext.Current.Error != null ? (HttpContext.Current.Error.InnerException != null ? HttpContext.Current.Error.InnerException.Message : string.Empty) : string.Empty; Label1.Text = message;
三、在web.config中配置
出現錯誤後跳轉到ErrorPage.aspx,和Application_Error相似,採用redirectMode模式能夠傳遞異常到錯誤頁面。dom
四、使用FirstChance異常通知。wordpress
關聯到AppDomain,若是應用程序域內發生異常,則會首先觸發這個事件,而後才查找catch塊處理異常。不過在這個事件中不能處理異常,不能消滅異常,只是能夠按照通知進行處理。由於若是這裏處理了異常,catch塊就不能進行處理了。.net
void Application_Start(object sender, EventArgs e) { // 在應用程序啓動時運行的代碼 AppDomain.CurrentDomain.FirstChanceException += new EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs>(CurrentDomain_FirstChanceException); } void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e) { Console.WriteLine(e.Exception.Message); // 錯誤:響應在上下文中不能使用 // Response.Redirect("ErrorPage.aspx"); // 錯誤:未將對象引用設置到對象的實例 // Server.Transfer("ErrorPage.aspx"); }
五、綁定UnhandledException事件線程
關聯到AppDomain,關於這個事件並非每次都能觸發,和使用的方式有關,狀況比較多。通常狀況下咱們只能獲取這個異常,而不能阻止中斷應用程序。代理
下邊給出一個例子:日誌
void Application_Start(object sender, EventArgs e) { // 在應用程序啓動時運行的代碼 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.Exception.Message); }
通常的未處理異常都會被Application_Error捕捉到,咱們這裏在線程中拋出一個異常。
另外StackOverflowException在.net4中再也不能被UnhandledException捕捉到。對象
private void CutString() { //throw (new Exception("Test Unhandled exception")); //throw (new StackOverflowException("Test Unhandled exception")); } protected void Button1_Click(object sender, EventArgs e) { Thread th = new Thread(new ThreadStart(CutString)); th.Start(); }
更多請參考:
http://msdn.microsoft.com/zh-Cn/library/system.appdomain.unhandledexception.aspx
http://mlichtenberg.wordpress.com/2011/09/19/catching-unhandled-exceptions-in-asp-net/
六、延伸:子線程異常的處理。網上有介紹經過代理在主線程處理子線程的異常,可是在asp.net中是無狀態的,主線程有可能很快消失,其中的某些處理可能執行失敗。
這裏使用Thread.Sleep使主線程不會很快結束。這種異常處理起來很麻煩,不建議在asp.net中使用處理時間很長的線程。
protected void Button1_Click(object sender, EventArgs e) { Thread th = new Thread(new ThreadStart(() => { try { throw (new Exception("Test Unhandled exception")); } catch (Exception ex) { //跳轉到錯誤頁面 Response.Redirect("ErrorPage.aspx"); } })); th.Start(); // asp.net主線程會很快結束,這裏讓他等等頁面跳轉。 Thread.Sleep(2000); }
本文列舉了處理異常的幾種方式,有經過訂閱AppDomain事件的方式,有經過配置文件的方式,還有經過Global的方式,最後還對子線程異常的處理談了一點想法,可是都沒有提供一個完善的解決方案,有興趣的朋友能夠本身試試。
我的獨立博客:http://blog.bossma.cn/dotnet/asp-net-resolve-exception-some-methods/