<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      eaglet

      本博專注于基于微軟技術的搜索相關技術
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      .Net 下未捕獲異常的處理

      Posted on 2009-02-17 09:53  eaglet  閱讀(19589)  評論(27)    收藏  舉報

      .Net 下未捕獲異常的處理

       作者:Eaglet

            隨著.Net技術的發展,.Net技術被逐漸應用到很多大型的應用軟件項目中。這些項目的規模越來越大,很多項目中除了自己的代碼外還引用了很多第三方的.net組件。同時很多項目又被應用到很多關鍵的部門,軟件系統的穩定性越來越至關重要。由于.Net 框架提供了非常強大的異常處理機制,同時對一些非托管代碼很難控制的系統問題比如指針越界,內存泄漏等提供了很好的解決方案。相比非托管代碼構建的系統,.Net構建的系統更加穩定。不過這并不是說.Net構建的系統就完全無懈可擊,很多由于代碼的不嚴謹或者系統問題引發的故障將會導致.Net應用程序產生未捕獲異常,從而導致應用程序異常終止。本文將對三種最常見的.Net應用的未捕獲異常處理進行闡述。

            在開始本文之前,讓我們來看看.Net在什么情況下會產生未捕獲異常。未捕獲異常從定義上說就是結構化異常處理未能捕獲的異常。通俗的講就是發生在Try Catch塊意外的異常。那么是不是我們在Main函數中加一個Try Catch 塊就可以捕獲全部未捕獲異常了呢?答案是否定的。這里面有兩種情況無法通過這種方法捕獲:

      1. GC 產生的異常,這種異常通常因為Finalize函數中引發未捕獲異常引起。當然這并不絕對,一些系統問題比如內存耗盡有時候也會造成GC異常。

      2. 主線程以為的線程引發的未捕獲異常。這些異常我們往往可以在線程的主函數中用Try Catch 來捕獲,但如果系統中使用了外部的組件,或者甚至是.Net 框架自帶的一些系統組件,由這些組件的線程引發的異常,調用代碼無法通過Try Catch來捕獲。

      從上面兩點來看,即使我們的代碼在每個地方都加了Try Catch ,也不能百分百杜絕未捕獲異常的發生。

      鑒于此,為了提高系統的健壯性和可維護性,我們需要通過一種方法來截獲這些未捕獲異常,并進行適當的處理。

      .Net 的設計者已經考慮到這些問題,并且為我們提供了一個叫 UnhandledExceptionEventHandler 的事件,通過這個事件,我們可以截獲未捕獲異常,并進行處理。

      這個事件的事件參數UnhandledExceptionEventArgs e, 有兩個屬性,一個是ExceptionObject,這個屬性返回為截獲異常的對象實例。還有一個屬性是IsTerminating,這個屬性告訴我們這個異常是否會導致應用終止。這里需要說明的是,對于.Net1.1 和 .Net2.0及以上,情況是不一樣的,.Net1.1 只有在主線程中的未捕獲異常才會終止應用程序,而.Net2.0及以上版本則是始終終止應用程序。如果不終止應用程序,而是有CLR 將當前異常消化,系統的運行狀態很可能不可控,最后可能會發生更大的故障,所以.Net2.0以后,對于所有未捕獲異常,一律終止當前應用。這樣看來,對于.net2.0以上的應用似乎我們截獲未捕獲異常已經毫無意義,其實不然。通過截獲為未捕獲異常,我們可以記錄下程序是再哪里產生這種未捕獲異常的,以便程序的開發者改進程序。我們也可以在當前應用退出前為系統做一些其他的保護工作,比如備份數據,告警提示等等。

      下面我們來看看三種常見的.Net應用分別如何來截獲未捕獲異常。

      • 控制臺應用

        

           首先為當前AppDomain 添加  UnhandledExceptionEventHandler

      AppDomain.CurrentDomain.UnhandledException += 

                   new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);

       

           再添加事件響應函數

              static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
              
      {
                  
      try
                  
      {

                      using (System.IO.FileStream fs = new System.IO.FileStream(@"c:\testme.log"

                               System.IO.FileMode.Append, System.IO.FileAccess.Write))

                      {

                          using (System.IO.StreamWriter w = new System.IO.StreamWriter(fs, 

                                   System.Text.Encoding.UTF8))

                          {
                              w.WriteLine(e.ExceptionObject);
                          }

                      }

                  }

                  
      catch
                  
      {
                  }

              }

       

      現在我們就可以截獲未捕獲異常了

      下面是完整的測試代碼:


              public class TestRaiseException
              
      {
                  
      ~TestRaiseException()
                  
      {
                      
      int i = 0;
                      
      int j = 1 / i;
                  }

              }


              
      static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
              
      {
                  
      try
                  
      {

                      using (System.IO.FileStream fs = new System.IO.FileStream(@"c:\testme.log",

                            System.IO.FileMode.Append, System.IO.FileAccess.Write))

                       {

                          using (System.IO.StreamWriter w = new System.IO.StreamWriter(fs, 

                               System.Text.Encoding.UTF8))

                           {

                              w.WriteLine(e.ExceptionObject);
                          }

                      }

                  }

                  
      catch
                  
      {
                  }

              }


              
      static void Main(string[] args)
              
      {

                  AppDomain.CurrentDomain.UnhandledException += 

                          new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);

       

       

                  TestRaiseException testRaiseException = new TestRaiseException();

              }

       

       程序運行后記錄下日志如下

      System.DivideByZeroException: Attempted to divide by zero.
         at TestCosole.Program.TestRaiseException.Finalize()

       

      • WinForm

          WinForm 應用通過 Application.ThreadException 事件來截獲未捕獲異常

        詳見 園子里面另一篇博客,這里就不再冗訴。

           體面地處理程序的未捕獲異常

      • Asp.net

           ASP.NET 應用和前兩種應用有所不同,ASP.NET 一般在后臺線程或者線程池中產生未捕獲異常,才會導致W3WP.exe終止,并在事件查看器中產生一條類似下面內容的事件:EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 app_web_ncsnb2-n, P5 0.0.0.0, P6 440a4082, P7 5, P8 1, P9 system.nullreferenceexception, P10 NIL. 

           要截獲ASP.NET 的未捕獲異常,我們需要為每個應用程序域安裝事件鉤子

           這個過程需要分兩步完成:

           首先創建一個實現IHttpModule接口的類 


      using System;
      using System.Data;
      using System.Configuration;
      using System.Web;
      using System.Web.Security;
      using System.Web.UI;
      using System.Web.UI.WebControls;
      using System.Web.UI.WebControls.WebParts;
      using System.Web.UI.HtmlControls;

      namespace WebMonitor
      {
          
      /// <summary>
          
      /// Summary description for UnhandledExceptionModule
          
      /// </summary>

          public class UnhandledExceptionModule : IHttpModule
          
      {
              
      static object _initLock = new object();
              
      static bool _initialized = false;

              
      public UnhandledExceptionModule()
              
      {
                  
      //
                  
      // TODO: Add constructor logic here
                  
      //
              }



              
      void OnUnhandledException(object o, UnhandledExceptionEventArgs e)
              
      {
                  
      //Do some thing you wish to do when the Unhandled Exception raised.

                  
      try
                  
      {

                      using (System.IO.FileStream fs = new System.IO.FileStream(@"c:\testme.log"

                              System.IO.FileMode.Append, System.IO.FileAccess.Write))

                       {

                          using (System.IO.StreamWriter w = new System.IO.StreamWriter(fs, System.

                                  Text.Encoding.UTF8))

                           {

                              w.WriteLine(e.ExceptionObject);
                          }

                      }

                  }

                  
      catch
                  
      {
                  }

              }

              
      IHttpModule Members
          }

      }

       

       第二步:

       修改web.config

      在 system.web 段中加入

          <httpModules>
            
      <add name="UnhandledExceptionModule" type="WebMonitor.UnhandledExceptionModule" />
            
          
      </httpModules>

       

       完成這兩步后,你的ASP.NET 應用就可以截獲未捕獲異常了。

       下面是測試代碼

       

      using System;
      using System.Data;
      using System.Configuration;
      using System.Web;
      using System.Web.Security;
      using System.Web.UI;
      using System.Web.UI.WebControls;
      using System.Web.UI.WebControls.WebParts;
      using System.Web.UI.HtmlControls;

      public partial class _Default : System.Web.UI.Page 
      {
          protected void Page_Load(object sender, EventArgs e)
          {

          }

          protected void TestMe(object state)
          {
              byte[] buf = new byte[2];
              buf[2] = 0;
          }

          protected void Button1_Click(object sender, EventArgs e)
          {

              System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(TestMe), 

                        null);

       

           }

      }


       按下Button1后,w3wp.exe被終止,testme.log 中記錄下了異常信息如下:

      System.IndexOutOfRangeException: Index was outside the bounds of the array.

         at _Default.TestMe(Object state) in c:"ApolloWorkFolder"test"laboratory

      "TestWebSite"Default.aspx.cs:line 21

         at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
         at System.Threading.ExecutionContext.runTryCode(Object userData)

         at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(

      TryCode code, CleanupCode backoutCode, Object userData)

         at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,

      ContextCallback callback, Object state)

         at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,

      ContextCallback callback, Object state)

         at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(

      _ThreadPoolWaitCallback tpWaitCallBack)

         at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)


      主站蜘蛛池模板: 性姿势真人免费视频放| 性欧美老妇另类xxxx| 国产欧美日韩精品丝袜高跟鞋| 亚洲日韩一区二区| 免费观看欧美猛交视频黑人| 欧洲码亚洲码的区别入口 | 奇米四色7777中文字幕| 国产精品人妻在线观看| 国产精品av中文字幕| 亚洲免费观看一区二区三区| 麻豆精品一区二区综合av| 男女性高爱潮免费网站| 国产精品va无码一区二区| 色综合色综合综合综合综合| 97久久精品人人澡人人爽| 国产成人精品视频不卡| 丰满少妇在线观看网站| 92精品国产自产在线观看481页| 国产偷国产偷亚洲高清午夜 | 亚洲精品综合第一国产综合| 亚洲中文字幕日产无码成人片| 亚洲免费网站观看视频| 久久综合九色综合久桃花| 亚洲 日本 欧洲 欧美 视频| 亚洲欧美日韩久久一区二区| 久久精品蜜芽亚洲国产AV| 久久精品视频这里有精品| 免费高潮了好湿h视频| 日韩av综合免费在线| 人妻中文字幕一区二区视频| 国产不卡一区不卡二区| 亚洲欧美中文日韩在线v日本| 日韩一区二区三区日韩精品| 美国又粗又长久久性黄大片| 久久久亚洲欧洲日产国码αv | 亚洲综合精品一区二区三区| 72种姿势欧美久久久久大黄蕉| 精品999日本久久久影院| 午夜射精日本三级| 色综合五月伊人六月丁香| 午夜免费福利小电影|