2012-09-25 10 views
25

Es ist wirklich interessant, dass der folgende C# -Code auf .NET4.0 abstürzt, aber auf .NET2 gut funktioniert.Warum AccessViolationException von .NET4.0 nicht abgefangen werden kann

C# -Code

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++ Code

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

die oben C# -Code gegen .NET2.0 Wenn kompilieren, funktioniert alles einwandfrei. Nur wenn es gegen .NET4.0 kompiliert wird, wird es zur Laufzeit abstürzen.

Ich vermute, dass System Ausnahme Catch-Mechanismus seit .NET4.0 geändert wurde. Irgendwelche Ideen?

Antwort

47

Ja, es in .NET geändert 4. Sie können keine Ausnahmen abfangen, die einen beschädigten Zustand anzeigen. Dies liegt daran, dass es praktisch keine Garantie gibt, dass Sie überhaupt etwas tun können, wenn eine beschädigte Ausnahme ausgelöst wird. Es gibt praktisch keinen Grund dafür, dass ein Prozess mit einem beschädigten Zustand fortgesetzt werden soll.

Aus Gründen der Kompatibilität mit älterem Code können Sie dieses Verhalten ändern, indem Sie das Element legacyCorruptedStateExceptionsPolicy zu app.config hinzufügen.

Sie können dies auch von Fall zu Fall tun, indem Sie Methoden markieren, bei denen Sie diese Ausnahmen mit der HandleProcessCorruptedStateExceptions attribute abfangen möchten.

+0

Große Antwort. Danke vielmals!!!! Diese Frage verwirrte mich lange Zeit. –

+1

Ich habe dieses Problem seit einer Woche verfolgt! Die eine Sache, die ich nützlich mit meinem verdorbenen Zustand tun kann, ist Neustart. Es ist eine Konsolen-App, die * 24 Stunden am Tag * laufen sollte. Jetzt wird es. – Andiih

+0

@Andiih, es sei denn, die beschädigten Bits sind der Code, der es neu starten würde. Ich würde zu diesem Zweck externe Wachhunde verwenden. –

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; 
    } 
Verwandte Themen