为什么.NET4.0无法捕获AccessViolationException
非常有趣的是,以下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; }
如果针对.NET2.0编译上面的C#代码,一切正常。 只针对.NET4.0进行编译会使其在运行时崩溃。
我怀疑自.NET4.0以来系统exception捕获机制已经改变。 有任何想法吗?
是的,它在.NET 4中发生了变化。您无法捕获表明状态已损坏的exception。 这是因为当抛出损坏的状态exception时,几乎不能保证你可以做任何事情。 实际上没有理由希望具有损坏状态的进程继续执行。
为了与旧代码兼容,您可以通过将legacyCorruptedStateExceptionsPolicy
元素添加到app.config来更改此行为。
您也可以通过使用HandleProcessCorruptedStateExceptions属性标记要捕获这些exception的方法, 逐个进行 。
[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; }