日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)C#.NET → 淺析VS2010 .NET 4.0里異常處理的新機制

      淺析VS2010 .NET 4.0里異常處理的新機制

      相關軟件相關文章發(fā)表評論 來源:本站整理時間:2010/9/5 20:39:52字體大小:A-A+

      作者:佚名點擊:375次評論:0次標簽: VS2010 .NET

      • 類型:休閑益智大小:113M語言:中文 評分:10.0
      • 標簽:
      立即下載

      前幾天,有一個朋友問我為什么在.NET里不能捕捉(catch)到一些異常了,而且在調(diào)試器里也捕捉不到。研究了一下,是.NET 4.0里新的異常處理機制搗的鬼。

       

      在.NET 4.0之后,CLR將會區(qū)別出一些異常(都是SEH異常),將這些異常標識為破壞性異常(Corrupted State Exception)。針對這些異常,CLR的catch塊不會捕捉這些異常,即使你用類似下面的代碼:

      try
      {
      TestMethod();
      }
      catch (Exception e)
      {
      Console.WriteLine("Catching exception: {0}", e);
      }

      也沒有辦法捕捉到這些異常。之所以要這樣設計,在MSDN的文章Handling Corrupted State Exceptions里已經(jīng)提到了。即,有一些支持插件的程序,例如Visual Studio或者SQL Server,它們支持調(diào)用托管代碼編寫成的插件,但是它們自己本身有很多代碼是由非托管的C++寫成的。由于插件經(jīng)常會調(diào)用到非托管的API,而很多時間,這些插件的代碼根本就不知道如何處理非托管的API拋出來的SEH異常。在4.0以前,因為SEH異常被轉換成了跟普通.NET異常相同的異常,這樣程序員只要用catch ( Exception e)的模式就可以捕捉到所有的異常。這樣處理的問題是,由于SEH異常通常都不是托管代碼拋出的,托管代碼根本就不知道SHE異常被扔出來的原因,簡單的catch ( Exception e)處理使得整個程序會處于一個非常不穩(wěn)定的狀態(tài),使得前面被忽略的問題在后面以更嚴重的方式出現(xiàn) — 例如保存被破壞的數(shù)據(jù)。這樣,看起來使用catch ( Exception e)處理所有的異常的方法很簡單,但實際上讓程序員或者用戶在問題延后發(fā)生時,分析起來需要花費更多的精力。

       

      因此在4.0以后,大部分SHE(我懷疑是所有)異常都被標識成破壞性異常,在.NET里,默認情況下CLR不會捕捉它們,而是任由操作系統(tǒng)來處理—即關閉程序,并打開一個錯誤對話框通知用戶。為了保證兼容性,在4.0以前編譯的程序,例如在2.0、3.0和3.5編譯的程序,依然采用的是老的策略—即.NET會同時捕捉.NET異常和SHE異常。而在4.0下面編譯的程序才會使用新的策略,這也是在文章的開頭,我的朋友所碰到的問題。你可以在.NET 4.0下面編譯下面的程序,體驗一下這個新變化:

       

      Program.cs:

      using System; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { [DllImport("Ref.dll")] private extern static void TestMethod(); static void Main(string[] args) { try { TestMethod(); } catch (Exception e) { Console.WriteLine("Catching exception: {0}", e); } } } }
       

       

      Ref.cpp:

      #include "stdafx.h" extern "C" __declspec(dllexport) void TestMethod() { int *p = NULL; // 會導致.NET拋出一個AccessViolation異常 *p = 10; }

       

      上面的代碼里,Program.cs使用P/Invoke技術調(diào)用了Ref.dll文件里的TestMethod,但是TestMethod嘗試給一個空指針賦值,導致一個AccessViolation異常。如果你在2.0下面編譯program.cs,并執(zhí)行的話,這個AccessViolation異常會被catch(Exception e)捕捉到,而如果你在4.0下面編譯并執(zhí)行的話,你會發(fā)現(xiàn)catch (Exception e)是不能捕捉到這個異常的。

       

      然而并不是所有人都想要這個新的異常機制,如果你的程序是在4.0下面編譯并運行,而你又想在.NET程序里捕捉到SHE異常的話,有兩個方案可以嘗試:

      1. 在托管程序的.config文件里,啟用legacyCorruptedStateExceptionsPolicy這個屬性,即簡化的.config文件類似下面的文件:

       

      App.config:

      <?xml version="1.0"?>
      <configuration>
       <startup>
       <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
       </startup>
      <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
      </runtime>
      </configuration>
       

       

      這個設置告訴CLR 4.0,整個.NET程序都要使用老的異常捕捉機制。

       

      2. 在需要捕捉破壞性異常的函數(shù)外面加一個HandleProcessCorruptedStateExceptions屬性,這個屬性只控制一個函數(shù),對托管程序的其他函數(shù)沒有影響,例如:

      [HandleProcessCorruptedStateExceptions] static void Main(string[] args) { try { TestMethod(); } catch (Exception e) { Console.WriteLine("Catching exception: {0}", e); } }

       

      你也可以下載示例代碼自己試一下(需要VS 2010才能編譯):
       

      /Files/killmyday/CSEsample.zip

        相關評論

        閱讀本文后您有什么感想? 已有人給出評價!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評論

        最新評論

        發(fā)表評論 查看所有評論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字數(shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)