而不是使用<legacyCorruptedStateExceptionsPolicy>
它会更好地使用[HandleProcessCorruptedStateExceptions]
(and [SecurityCritical]
) ,如下所述:
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx
之后,您的Main
方法应如下所示:
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main(string[] args)
{
try
{
...
}
catch (Exception ex)
{
// Log the CSE.
}
}
但请注意,这不会捕获更严重的异常,例如StackOverflowException
and ExecutionEngineException
。
finally
涉及的块也try
不会被执行:
https://csharp.2000things.com/2013/08/30/920-a-finally-block-is-not-executed-when-a-corrupted-state-exception-occurs/
对于其他未处理的 appdomain 异常,您可以使用:
AppDomain.CurrentDomain.UnhandledException
Application.Current.DispatcherUnhandledException
TaskScheduler.UnobservedTaskException
(当特定处理程序适合您的情况时,请搜索详细信息。TaskScheduler.UnobservedTaskException
例如有点棘手。)
如果您无权访问该Main
方法,您还可以标记您的 AppDomain 异常处理程序以捕获 CSE:
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
...
[HandleProcessCorruptedStateExceptions, SecurityCritical]
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// AccessViolationExceptions will get caught here but you cannot stop
// the termination of the process if e.IsTerminating is true.
}
最后一道防线可能是这样的非托管 UnhandledExceptionFilter:
[DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
private static extern int SetUnhandledExceptionFilter(Callback cb);
// This has to be an own non generic delegate because generic delegates cannot be marshalled to unmanaged code.
private delegate uint Callback(IntPtr ptrToExceptionInfo);
然后在您的流程开始的某个地方:
SetUnhandledExceptionFilter(ptrToExceptionInfo =>
{
var errorCode = "0x" + Marshal.GetExceptionCode().ToString("x2");
...
return 1;
});
您可以在此处找到有关可能的返回码的更多信息:
https://msdn.microsoft.com/en-us/library/ms680634(VS.85).aspx
的一个“特点”UnhandledExceptionFilter
是,如果附加了调试器,则不会调用它。(至少在我拥有 WPF 应用程序的情况下没有。)所以请注意这一点。
如果您从上面设置了所有适当的 ExceptionHandler,您应该记录所有可以记录的异常。对于更严重的异常(如StackOverflowException
and ExecutionEngineException
),您必须找到另一种方法,因为在它们发生后整个过程无法使用。一种可能的方法可能是另一个监视主进程并记录任何致命错误的进程。
附加提示: