Как обрабатывать AccessViolationException
Вопрос
Я использую COM-объект (MODI) из моего .NET приложения. Метод, который я звоню бросает систему .accessviolationException, который перехвачен Visual Studio. Странно, что я обернул свой звонок в попытке попробовать, который имеет обработчики для AccessViolationException, ComException и все остальное, но когда Visual Studio (2010) перехватывает AccessViolationException, отладчик перерывается на вызов метода (DOC.con), И если я прохожу, это продолжается на следующей строке вместо ввода блока Catch. Кроме того, если я запускаю это за пределами Visual Studio My Applications. Как я могу справиться с этим исключением, который брошен в 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();
}
Решение
В .NET 4.0 время выполнения обрабатывает определенные исключения, поднятые в виде ошибок (SEH SEH) Windows структурированной ошибки (SEH) в качестве индикаторов поврежденного состояния. Эти поврежденные исключения государства (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. для деталей.
РЕДАКТИРОВАТЬ
Ранее я ссылался на Форум пост Для дополнительных деталей. Но поскольку Microsoft Connect была на пенсии, вот дополнительные данные в случае вас интересно:
От Гаурава Ханны, разработчик из команды Microsoft CLR
Это поведение по дизайну из-за особенности CLR 4.0 называется поврежденными исключениями состояния. Проще говоря, управляемый код не должен сделать попытку ловить исключения, которые указывают на поврежденное состояние процесса, и AV является одним из них.
Затем он продолжает ссылаться на документацию на HandleProcessCorruptStateExceptionSattribute и вышеуказанная статья. Достаточно сказать, это определенно стоит читать, если вы рассматриваете охватывание этих типов исключений.
Другие советы
Добавьте следующее в файле конфигурации, и он будет пойман в Trom Catch Block. Слово осторожности ... Попробуйте избежать этой ситуации, как это означает, что какое-то нарушение происходит.
<configuration>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
</configuration>
Составлено сверху ответов, работал для меня, сделали следующие шаги, чтобы поймать его.
Шаг № 1 - Добавьте следующий фрагмент в файл конфигурации
<configuration>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
</configuration>
Шаг 2
Добавлять -
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
В верхней части функции вы связываете, чтобы поймать исключение
источник: http://www.gisremoteSensing.com/2017/03/catch-exception-athted-to-Read-or.html.
Вы можете попробовать использовать Appdomain.unhandledException. И посмотрите, что это позволяет вас поймать.
**РЕДАКТИРОВАТЬ*
Вот некоторые больше информации Это может быть полезно (это давно читается).