2012-09-25 17 views
25

Es realmente interesante que el siguiente código C# se bloqueará en .NET4.0 pero funcionará bien en .NET2.0.Por qué AccessViolationException no puede ser capturado por .NET4.0

código 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ódigo C++

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

Si compilar el código # C por encima contra .NET2.0, todo funciona bien. Solo compilarlo contra .NET4.0 lo hará bloquearse en tiempo de ejecución.

Estoy sospechando que el mecanismo de excepción de sistema ha sido cambiado desde .NET4.0. ¿Algunas ideas?

Respuesta

47

Sí, cambió en .NET 4. No puede detectar excepciones que indiquen un estado dañado. Esto se debe a que prácticamente no hay garantía de que pueda hacer nada en absoluto cuando se produce una excepción de estado dañado. Prácticamente no hay ninguna razón para querer que un proceso con estado dañado continúe ejecutándose.

Para compatibilidad con código anterior, puede cambiar este comportamiento agregando el elemento legacyCorruptedStateExceptionsPolicy a app.config.

También puede hacerlo caso por caso marcando los métodos en los que desea capturar estas excepciones con el HandleProcessCorruptedStateExceptions attribute.

+0

Great answer. ¡¡¡¡Muchas gracias!!!! Esta pregunta me confundió por mucho tiempo. –

+1

¡He estado persiguiendo este problema por una semana! La única cosa que puedo hacer con mi estado corrupto es reiniciar. Es una aplicación de consola que * debería * funcionar las 24 horas del día. Ahora lo hará. – Andiih

+0

@Andiih a menos que los bits dañados sean el código que lo reiniciaría. Usaría perros guardianes externos para este propósito. –

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; 
    } 
Cuestiones relacionadas