为什么.NET4.0无法捕获AccessViolationException异常

28

以下C#代码在.NET 4.0上会崩溃,但在.NET 2.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以来,系统异常捕获机制发生了改变。有什么想法吗?

2个回答

50

是的,在.NET 4中有所改变。您无法捕获指示出现损坏状态的异常。这是因为当抛出损坏状态异常时,您几乎没有任何保证可以采取任何措施。让处于损坏状态的进程继续执行几乎没有任何理由。

为了与旧代码兼容,您可以通过将legacyCorruptedStateExceptionsPolicy元素添加到app.config来更改此行为。

您也可以按情况逐个标记方法,并使用HandleProcessCorruptedStateExceptions属性捕获这些异常。


1
我已经追踪这个问题一个星期了!我可以有用地处理我的损坏状态的唯一方法就是重新启动。这是一个控制台应用程序,应该全天候运行。现在它将会。 - Andiih
@Andiih,除非损坏的位是会重新启动它的代码,否则我会使用外部看门狗来实现此目的。 - R. Martinho Fernandes
谢谢。我们也有一个外部看门狗(已经有一段时间了),但这使得重新启动更快,如果可能的话。 - Andiih

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接