为啥 AccessViolationException 不能被 .NET4.0 捕获
Posted
技术标签:
【中文标题】为啥 AccessViolationException 不能被 .NET4.0 捕获【英文标题】:Why AccessViolationException cannot be caught by .NET4.0为什么 AccessViolationException 不能被 .NET4.0 捕获 【发布时间】:2012-09-25 10:38:04 【问题描述】:下面的 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 以来系统异常捕获机制已更改。有什么想法吗?
【问题讨论】:
【参考方案1】:是的,它在 .NET 4 中发生了变化。您无法捕获指示损坏状态的异常。这是因为当一个损坏的状态异常被抛出时,几乎不能保证你可以做任何事情。实际上没有理由希望状态已损坏的进程继续执行。
为了与旧代码兼容,您可以通过将 legacyCorruptedStateExceptionsPolicy
元素添加到 app.config 来更改此行为。
您也可以根据具体情况使用HandleProcessCorruptedStateExceptions attribute 标记要捕获这些异常的方法。
【讨论】:
我已经关注这个问题一周了!我可以对损坏的状态有用的一件事是重新启动。它是一个应该每天 24 小时运行的控制台应用程序。现在它会的。 @Andiih 除非损坏的位是重新启动它的代码。为此,我会使用外部看门狗。 谢谢。我们也有一个外部看门狗(已经有一段时间了),但这可以在可能的情况下更快地重启。【参考方案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;
【讨论】:
以上是关于为啥 AccessViolationException 不能被 .NET4.0 捕获的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?