Как обращаться с AccessViolationException

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

}

Ответ 1

В .NET 4.0 среда выполнения обрабатывает определенные исключения, возникающие как ошибки Windows Structured Error Handling (SEH) как индикаторы Corrupted State. Эти Исключенные Исключения Исключения (CSE) не могут быть уловлены вашим стандартным управляемым кодом. Я не буду вдаваться в то, почему и как здесь. Прочтите эту статью о CSE в платформе .NET 4.0:

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

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

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

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

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

Дополнительная информация: http://connect.microsoft.com/VisualStudio/feedback/details/557105/unable-to-catch-accessviolationexception

Ответ 2

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

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

Ответ 3

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

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

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

Шаг # 2

Добавить -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]

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

источник: http://www.gisremotesensing.com/2017/03/catch-exception-attempted-to-read-or.html