我通过使用 3 个不同的异常处理程序来解决此问题,具体取决于抛出异常的方式和位置,您需要单独捕获它。这也使您有机会根据您自己对异常是否致命的决定来取消终止并继续程序执行。
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
public class ExceptionHelper
{
public static ExceptionHelper()
{
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
Application.Current.Dispatcher.UnhandledException += DispatcherOnUnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
}
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
e?.SetObserved();
CurrentDomainUnhandledException(sender, new UnhandledExceptionEventArgs(e.Exception, false));
}
private static void DispatcherOnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
CurrentDomainUnhandledException(sender, new UnhandledExceptionEventArgs(e.Exception, false));
}
public static void CurrentDomainUnhandledException(object sender, [CanBeNull] UnhandledExceptionEventArgs e)
{
//Program is hung, ensure we don't infinite loop on outofmemory exception by removing the handler
var isTerminating = e?.IsTerminating == true;
if (isTerminating)
{
TaskScheduler.UnobservedTaskException -= TaskSchedulerOnUnobservedTaskException;
Application.Current.Dispatcher.UnhandledException -= DispatcherOnUnhandledException;
AppDomain.CurrentDomain.UnhandledException -= CurrentDomainUnhandledException;
}
var ex = (Exception)e?.ExceptionObject;
//Kill the app if we weren't already terminating and the program is in a corrupted state.
if(!isTerminating)
Process.GetCurrentProcess().Kill();
}
}