是否有可能在.NET中捕获访问冲突异常?
你不应该。访问冲突是一个严重的问题:这是意外的尝试写入(或读取)无效的内存地址。正如John已经阐明的那样,在引发访问冲突之前,非托管DLL可能已经损坏了进程内存。这可能对当前过程的任何部分产生不可预测的影响。
最安全的事情是可能通知用户,然后立即退出。
一些更多细节:访问冲突是一个操作系统异常(所谓的SEH或结构化异常处理异常)。这是与System.Exception
的托管CLR例外不同的例外情况。您很少会在纯粹的托管代码中看到SEH异常,但是如果出现这种异常,例如在非托管代码中,CLR会将其交给托管代码,您也可以在其中捕获它。
然而,捕SEH异常大多不是一个好主意。进一步的细节在MSDN杂志文章Handling Corrupted State Exceptions在下面的文本从采取的解释:使用相同的机制,通过程序本身引起的异常
的CLR一贯提供的SEH例外托管代码。只要代码不尝试处理无法合理处理的异常情况,这就不成问题。访问冲突后,大多数程序无法安全地继续执行。不幸的是,CLR的异常处理模型一直鼓励用户通过允许程序捕获System.Exception层次结构顶部的任何异常来捕获这些严重错误。但这很少是正确的。
这是真的,直到.NET 3.5。在.NET 4中,行为已经改变。如果您仍然希望能够捕捉到这种异常情况,则必须将legacyCorruptedStateExceptionsPolicy=true
添加到app.config。上面链接的进一步细节。
您可以使用try-catch块将调用包装为非托管DLL。 AccessViolationExceptions可以正常抓到。执行以下代码显示了两个消息:
try
{
throw new AccessViolationException();
}
catch (Exception e)
{
MessageBox.Show(e.Message + e.StackTrace, e.Message, MessageBoxButtons.OK, MessageBoxIcons.Error);
}
MessageBox.Show("Still running..");
编辑: .NET 4中引入的一个change in behavior,它不再可能赶上损坏状态的异常,除非您特别"ask"运行时这样做。
首先我用0xA3执行完全ACK。但是,如果没有出路,你可以将脏的非托管DLL包装在自己的进程中,并通过IPC(TCP/IP,namedpipes等)传输数据。捕获所有异常并通知主机进程。所以你的主机进程主要是从内存损坏中保存。
是。
在你的应用程序。CONFG,扑通的<configuration>
标记中下面的代码:
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
现在,你应该能够赶上损坏的状态异常(CSE)像任何其他。
注意:如果你已经有一个运行时的标签,然后简单地添加<legacyCorruptedStateExceptionsPolicy enabled="true"/>
它
上述作品.NET 4.5
为此。我读了几个关于这个问题的答案。所有人都说“将'legacyCorruptedStateExceptionsPolicy enabled =”true“/>'添加到'app.config'”,但没有人说这不应该在默认的“
正如其他人指出的那样,你不应该“处理”这一条件,但在开发过程中,为了排除故障,很方便。
您可以标记与System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions
属性的管理方法:
[HandleProcessCorruptedStateExceptions]
public void MyMethod()
{
try
{
NaughtyCall();
}
catch (AccessViolationException e)
{
// You should really terminate your application here
}
}
澄清:您希望退出ASAP的原因是,您不知道非托管DLL在达到访问冲突之前被覆盖的内容。它可能在足够的地方编写垃圾,导致程序无法安全地继续。 – 2010-07-22 18:38:55
@John Saunders:谢谢你的澄清。我更新了我的答案。 – 2010-07-22 18:47:31
我可以想到一个非常好的理由来解决这个问题:如果你有一个无人管理的进程,而你没有这个进程,而不是退出,那么这个进程将会挂起,访问冲突对话框会显示没有人。捕捉它可让您在没有弹出对话框的情况下退出。 – jpwkeeper 2013-05-16 14:09:48