2012-09-25 5 views
25

Il est vraiment intéressant que le code C# suivant plante sur .NET4.0 mais fonctionne correctement sur .NET2.0.Pourquoi AccessViolationException ne peut pas être interceptée par .NET4.0

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

Si la compilation du code ci-dessus C# contre .NET2.0, tout fonctionne bien. Seulement le compiler contre .NET4.0 le fera planter au moment de l'exécution.

Je soupçonne que le mécanisme de prise d'exception système a été modifié depuis .NET4.0. Des idées?

Répondre

47

Oui, cela a changé dans .NET 4. Vous ne pouvez pas détecter les exceptions qui indiquent un état corrompu. C'est parce qu'il n'y a pratiquement aucune garantie que vous pouvez faire quoi que ce soit du tout lorsqu'une exception d'état corrompue est levée. Il n'y a pratiquement aucune raison de vouloir continuer un processus avec un état corrompu.

Pour des raisons de compatibilité avec les anciens codes, vous pouvez modifier ce comportement en ajoutant l'élément legacyCorruptedStateExceptionsPolicy à app.config.

Vous pouvez également le faire au cas par cas en marquant les méthodes dans lesquelles vous voulez attraper ces exceptions avec HandleProcessCorruptedStateExceptions attribute.

+0

Bonne réponse. Merci beaucoup!!!! Cette question m'a embrouillé pendant longtemps. –

+1

Je poursuivais ce problème depuis une semaine! La seule chose que je peux utilement faire avec mon état corrompu est le redémarrage. C'est une application de console qui devrait fonctionner 24 heures par jour. Maintenant ça va. – Andiih

+0

@Andiih sauf si les bits corrompus sont le code qui le relancerait. J'utiliserais des chiens de garde externes à cette fin. –

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; 
    } 
Questions connexes