2012-09-25 14 views
25

To jest naprawdę interesujące, że następujący kod C# zostanie zawieszony na .NET4.0, ale działa poprawnie na .NET2.0.Dlaczego wyjątek AccessViolationException nie może zostać przechwycony przez .NET4.0

kod 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(); 
} 

kodu C++

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

Jeżeli powyższy kompilacji kodu C# przed .NET2.0, wszystko działa bez zarzutu. Kompilowanie go tylko przeciwko .NET4.0 spowoduje awarię.

Podejrzewam, że mechanizm przechwytywania wyjątków systemu został zmieniony od wersji .NET4.0. Jakieś pomysły?

Odpowiedz

47

Tak, zmieniło się w .NET 4. Nie można przechwytywać wyjątków wskazujących na uszkodzenie. Dzieje się tak dlatego, że nie ma gwarancji, że możesz zrobić cokolwiek, gdy zostanie zgłoszony wyjątek dotyczący uszkodzonego stanu. Nie ma praktycznie żadnego powodu, aby chcieć kontynuować proces ze skorumpowanym stanem.

Aby zachować zgodność ze starszym kodem, można zmienić to zachowanie, dodając element legacyCorruptedStateExceptionsPolicy do pliku app.config.

Możesz to również zrobić indywidualnie, zaznaczając metody, w których chcesz uchwycić te wyjątki za pomocą HandleProcessCorruptedStateExceptions attribute.

+0

Świetna odpowiedź. Wielkie dzięki!!!! To pytanie dezorientowało mnie przez długi czas. –

+1

Goniłem za tym problemem przez tydzień! Jedyne, co mogę z pożytkiem zrobić z moim uszkodzonym stanem, to ponowne uruchomienie. Jest to aplikacja konsolowa, która * powinna * działać 24 godziny na dobę. Teraz to zrobi. – Andiih

+0

@Andiih, chyba że uszkodzone bity są kodem, który uruchomi go ponownie. Do tego celu użyłbym zewnętrznych stróżów. –

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; 
    } 
Powiązane problemy