Почему AccessViolationException не может быть перехвачен .NET4.0

Действительно интересно, что следующий код C # будет аварийно завершен на .NET4.0, но отлично работает на .NET2.0.

Код C #

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 ++

extern "C" __declspec(dllexport) int ExceptionTest()
{
IUnknown* pUnk = NULL;
pUnk->AddRef();
return 0;
}

Если компилировать приведенный выше код C # для .NET2.0, все работает нормально. Только компиляция с использованием .NET4.0 приведет к сбою во время выполнения.

Я подозреваю, что механизм перехвата системных исключений был изменен с .NET4.0. Есть идеи?

28

Решение

Да, это изменилось в .NET 4. Вы не можете перехватывать исключения, которые указывают на поврежденное состояние. Это связано с тем, что практически нет никаких гарантий, что вы можете сделать что-либо вообще, когда выдается исключение из поврежденного состояния. Практически нет причин хотеть, чтобы процесс с поврежденным состоянием продолжал выполняться.

Для совместимости со старым кодом вы можете изменить это поведение, добавив legacyCorruptedStateExceptionsPolicy элемент к app.config.

Вы также можете сделать это на индивидуальной основе, отметив методы, где вы хотите перехватить эти исключения с помощью Атрибут HandleProcessCorruptedStateExceptions.

50

Другие решения

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector