ASP.NET中處理異常的幾種方式


1、程序中使用try catch
對於預知會發生異常的代碼段使用try catch主動捕獲異常,適用於提示給用戶或跳轉到錯誤頁面,或者通過其它方式處理異常(日志、通知等)。

int i = 10;
int j = 0;

try
{
Label1.Text = (i / j).ToString();
}
catch (Exception ex)
{
// 這里處理異常:Redirect、Transfer、Log、Notice等
Console.WriteLine("Page:" + ex.Message);
}

2、Global中使用Application_Error

如果異常在程序中沒有被處理(如沒有try catch),則異常的處理會流轉到這個方法,這里邊可以對異常進行處理。但是此方式不能捕捉子線程中的異常。

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;

3、在web.config中配置
出現錯誤后跳轉到ErrorPage.aspx,和Application_Error類似,采用redirectMode模式可以傳遞異常到錯誤頁面。

          
      

4、使用FirstChance異常通知。

關聯到AppDomain,如果應用程序域內發生異常,則會首先觸發這個事件,然后才查找catch塊處理異常。不過在這個事件中不能處理異常,不能消滅異常,只是可以按照通知進行處理。因為如果這里處理了異常,catch塊就不能進行處理了。

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");
}

5、綁定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/

6、延伸:子線程異常的處理。網上有介紹通過代理在主線程處理子線程的異常,但是在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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM