我已经阅读了一些其他线程和文章,建议有一种方法可以捕获源自非UI线程的未处理异常。出于某种原因,这对我不起作用。正在捕获未处理的UI异常。即使我通过从非UI线程中抛出异常进行测试,CurrentDomainUnhandledException也不会执行。
更奇怪的是,非UI线程上的异常并没有像我想象的那样关闭应用程序。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Application.Current.DispatcherUnhandledException += CurrentDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException +=
CurrentDomainUnhandledException;
}
void CurrentDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
MessageBox.Show(e.Exception.Message, "Caught an unhandled exception!");
}
void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
MessageBox.Show(ex.Message, "Uncaught Thread Exception",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
我从处理插入设备的事件处理程序中抛出,这绝对不是UI线程。调试器中断并向我显示异常未处理的消息。然而,当我继续应用程序继续运行并似乎继续工作。我为此感到困惑。
_devicePlugWatcher = new ManagementEventWatcher(pluggedQueryStr);
_devicePlugWatcher.EventArrived += (DevicePluggedEventReceived);
答案 0 :(得分:2)
如果在非线程池线程(或非AppDomain.CurrentDomain.UnhandledException
)上抛出异常,则应调用Task
事件处理程序。试试这个例子:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Thread thread = new Thread(() =>
{
Thread.Sleep(5000);
throw new Exception("test");
});
thread.Start();
}
void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
MessageBox.Show(ex.Message, "Uncaught Thread Exception",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
并将其与非观察Task
内发生异常的情况进行比较:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
Task.Run(() =>
{
throw new Exception("test");
});
Loaded += (s, e) =>
{
//gc so the unobserved exception "bubbles" up
GC.Collect(3, GCCollectionMode.Forced, true);
};
}
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
Exception ex = e.Exception;
MessageBox.Show(ex.Message, "Uncaught Thread Exception",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
所以你也应该处理TaskScheduler.UnobservedTaskException
。