Действительно интересно, что следующий код 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. Есть идеи?
Да, это изменилось в .NET 4. Вы не можете перехватывать исключения, которые указывают на поврежденное состояние. Это связано с тем, что практически нет никаких гарантий, что вы можете сделать что-либо вообще, когда выдается исключение из поврежденного состояния. Практически нет причин хотеть, чтобы процесс с поврежденным состоянием продолжал выполняться.
Для совместимости со старым кодом вы можете изменить это поведение, добавив legacyCorruptedStateExceptionsPolicy
элемент к app.config.
Вы также можете сделать это на индивидуальной основе, отметив методы, где вы хотите перехватить эти исключения с помощью Атрибут HandleProcessCorruptedStateExceptions.
[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;
}