Подтвердить что ты не робот

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

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

Код С#

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();
}

Код С++

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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