Как обращаться с AccessViolationException - PullRequest
166 голосов
/ 12 августа 2010

Я использую COM-объект (MODI) из моего приложения .net.Метод, который я вызываю, вызывает исключение System.AccessViolationException, которое перехватывается Visual Studio.Странно то, что я завернул свой вызов в ловушку try, в которой есть обработчики AccessViolationException, COMException и всего остального, но когда Visual Studio (2010) перехватывает AccessViolationException, отладчик прерывается при вызове метода (doc.OCR)и если я перейду, он перейдет к следующей строке вместо ввода блока catch.Кроме того, если я запускаю это за пределами Visual Studio, мое приложение вылетает.Как я могу обработать это исключение, которое выбрасывается в объекте 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();

}

Ответы [ 4 ]

277 голосов
/ 21 января 2011

В .NET 4.0 среда выполнения обрабатывает некоторые исключения, возникающие как ошибки структурированной обработки ошибок Windows (SEH), как индикаторы поврежденного состояния. Эти исключения из поврежденного состояния (CSE) не могут быть перехвачены вашим стандартным управляемым кодом. Я не буду разбираться в том, почему или как здесь. Прочтите эту статью о CSE в .NET 4.0 Framework:

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

Но есть надежда. Есть несколько способов обойти это:

  1. Перекомпилируйте как сборку .NET 3.5 и запустите ее в .NET 4.0.

  2. Добавьте строку в файл конфигурации вашего приложения в элементе configuration / runtime: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. Украсьте методы, в которые вы хотите перехватить эти исключения, атрибутом HandleProcessCorruptedStateExceptions. Подробнее см. http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035.


EDIT

Ранее я ссылался на сообщение на форуме для получения дополнительной информации. Но поскольку Microsoft Connect был удален, вот дополнительные сведения на тот случай, если вы заинтересованы:

От Гаурава Ханны, разработчика из команды Microsoft CLR

Такое поведение является конструктивным благодаря функции CLR 4.0, которая называется Исключения из-за поврежденного состояния. Проще говоря, управляемый код не должен пытаться перехватывать исключения, которые указывают на поврежденное состояние процесса, и AV является одним из них.

Затем он ссылается на документацию по HandleProcessCorruptedStateExceptionsAttribute и статье выше. Достаточно сказать, что, безусловно, стоит прочитать, если вы собираетесь ловить исключения такого типа.

13 голосов
/ 27 января 2014

Добавьте следующее в файл конфигурации, и оно будет перехвачено в блоке try catch. Слово предостережения ... попытайтесь избежать этой ситуации, поскольку это означает, что происходит какое-то нарушение.

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>
6 голосов
/ 22 марта 2017

Скомпилированный из приведенных выше ответов, работал для меня, сделал следующие шаги, чтобы поймать его.

Шаг # 1 - Добавить следующий фрагмент в файл конфигурации

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

Шаг # 2

Добавить -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]

в верхней части функции, которую вы связываете, поймать исключение

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

1 голос
/ 12 августа 2010

Вы можете попробовать использовать AppDomain.UnhandledException и посмотреть, позволяет ли это перехватить его.

** EDIT *

Вот некоторая дополнительная информация , которая может быть полезна (это длинное чтение).

...