web-dev-qa-db-fra.com

Comment gérer AccessViolationException

J'utilise un objet COM (MODI) à partir de mon application .net. La méthode que j'appelle lève une exception System.AccessViolationException, qui est interceptée par Visual Studio. La chose étrange est que j'ai encapsulé mon appel dans un catch try, qui contient des gestionnaires pour AccessViolationException, COMException et tout le reste, mais lorsque Visual Studio (2010) intercepte l'exception AccessViolationException, le débogueur interrompt l'appel de méthode (doc.OCR), et si je passe à travers, il continue à la ligne suivante au lieu d'entrer dans le bloc catch. De plus, si j'exécute ceci en dehors du studio visuel, mon application se bloque. Comment puis-je gérer cette exception qui est levée dans l'objet COM?

MODI.Document doc = new MODI.Document();
try
{
    doc.Create(sFileName);
    try
    {
        doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false);
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.AccessViolationException ex)
    {
        //MODI seems to get access violations for some reason, but is still able to return the OCR text.
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        //if no text exists, the engine throws an exception.
        sText = "";
    }
    catch
    {
        sText = "";
    }

    if (sText != null)
    {
        sText = sText.Trim();
    }
}
finally
{
    doc.Close(false);

    //Cleanup routine, this is how we are able to delete files used by MODI.
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
    doc = null;
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();

}
167
Jeremy

Dans .NET 4.0, le moteur d'exécution gère certaines exceptions déclenchées sous la forme d'erreurs SEH (Windows Structured Error Handling) en tant qu'indicateurs de l'état corrompu. Votre code géré standard ne peut pas intercepter ces exceptions d'état corrompu (CSE). Je ne vais pas entrer dans le pourquoi ou comment est ici. Lisez cet article sur le CST dans le .NET 4.0 Framework:

http://msdn.Microsoft.com/en-us/magazine/dd419661.aspx#id0070035

Mais il y a de l'espoir. Il y a plusieurs façons de contourner cela:

  1. Recompilez en tant qu'assemblage .NET 3.5 et exécutez-le dans .NET 4.0.

  2. Ajoutez une ligne au fichier de configuration de votre application sous l'élément configuration/runtime: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. Décorez les méthodes pour lesquelles vous voulez intercepter ces exceptions avec l'attribut HandleProcessCorruptedStateExceptions. Voir http://msdn.Microsoft.com/en-us/magazine/dd419661.aspx#id0070035 pour plus de détails.


EDIT

Auparavant, je faisais référence à post sur le forum pour plus de détails. Mais depuis que Microsoft Connect a été retiré, voici les détails supplémentaires au cas où cela vous intéresserait:

De Gaurav Khanna, développeur de l'équipe Microsoft CLR

Ce comportement est dû à une fonctionnalité de CLR 4.0 appelée Exceptions d’État corrompu, inhérente à sa conception. En termes simples, le code géré ne devrait pas tenter d'attraper les exceptions qui indiquent un état de processus corrompu, et AV est l'un d'entre eux.

Il se réfère ensuite à la documentation sur HandleProcessCorruptedStateExceptionsAttribute et à l'article ci-dessus. Autant dire que cela vaut vraiment la peine d’être lu si vous envisagez d’attraper ces types d’exceptions.

280
villecoder

Ajoutez ce qui suit dans le fichier de configuration, et il sera pris dans le bloc try catch. Mise en garde ... essayez d'éviter cette situation, car cela signifie qu'une sorte de violation est en train de se produire.

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>
14
Partha

Compilé à partir des réponses ci-dessus, travaillé pour moi, fait les étapes suivantes pour l'attraper.

Étape n ° 1 - Ajouter l'extrait suivant au fichier de configuration

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>

Étape 2

Ajouter -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]

sur le dessus de la fonction que vous attachez attraper l'exception

source: http://www.gisremotesensing.com/2017/03/catch-exception-attempted-to-read-or.html

7
EvilInside

Vous pouvez essayer d'utiliser AppDomain.UnhandledException et voir si cela vous permet de l'attraper.

**MODIFIER*

Voici quelques plus d'informations qui pourraient être utiles (la lecture est longue).

1
Tony Abrams