2012-09-25 93 views
25

下面的C#代碼會在.NET4.0上崩潰,但在.NET2.0上正常工作真的很有趣。爲什麼AccessViolationException不能被.NET4.0抓住

C#代碼

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      ExceptionTest(); 
      Console.WriteLine("Done!"); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error !!!"); 
      Console.WriteLine(e.Message); 
     } 
    } 

    [DllImport("badapp")] 
    private static extern int ExceptionTest(); 
} 

C++代碼

extern "C" __declspec(dllexport) int ExceptionTest() 
{ 
    IUnknown* pUnk = NULL; 
    pUnk->AddRef(); 
    return 0; 
} 

如果編譯針對.NET2.0上面的C#代碼,一切工作正常。只有使用.NET4.0進行編譯纔會使其在運行時崩潰。

我懷疑自.NET4.0以來,系統異常捕獲機制已被更改。有任何想法嗎?

回答

47

是的,它在.NET 4中進行了更改。您無法捕獲指示已損壞狀態的異常。這是因爲幾乎不能保證當拋出損壞的狀態異常時你可以做任何事情。實際上沒有理由希望處於狀態損壞的進程繼續執行。

爲了與舊代碼兼容,您可以通過將legacyCorruptedStateExceptionsPolicy元素添加到app.config來更改此行爲。

您也可以通過在HandleProcessCorruptedStateExceptions attribute之間標記想要捕獲這些例外情況的方法,逐案做到這一點。

+0

很好的回答。非常感謝!!!!這個問題困擾了我很長一段時間。 –

+1

我一直在追趕這個問題一個星期!我可以用我的損壞狀態有效地做的一件事是重新啓動。它的控制檯應用程序*應該*每天24小時運行。現在它會。 – Andiih

+0

@Andiih,除非被破壞的位是會重新啓動它的代碼。爲此,我會使用外部看門狗。 –

3
[HandleProcessCorruptedStateExceptions] 
    public static unsafe int LenghtPoint(this IntPtr point) 
    { 
     //por optimizar 
     byte* bytePoint = (byte*)point.ToPointer(); 
     byte auxByte; 
     int length = 1; 
     bool encontrado = false; 
     while (!encontrado) 
     { 

      try 
      { 

       auxByte = bytePoint[length]; 
       length++; 
      } 
      catch (System.AccessViolationException) 
      { 
       length--; 
       encontrado = true; 

      } 
     } 
     return length; 
    } 
相關問題