3:WPF中三种异常捕获:UI线程异常、非UI线程异常、Task线程异常
在窗体放一个按钮在单击事件执行如下代码来模拟。
private void Button_Click(object sender, RoutedEventArgs e) { //throw new InvalidOperationException("Something has gone wrong."); Thread t = new Thread(() => { throw new InvalidOperationException("Something has gone wrong."); }); t.IsBackground = true; t.Start(); //Task.Factory.StartNew(() => { throw new Exception("出错了"); }); }
三种解决方案:
private void App_Startup(object sender, StartupEventArgs e) { //处理UI线程异常 DispatcherUnhandledException += App_DispatcherUnhandledException; //处理非UI线程异常 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; //Task线程内异常 TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; }
/// <summary> /// 捕获到UI线程异常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { log.Exception("捕获到UI线程异常", e.Exception); e.Handled = true;//表示此异常已处理过 }
/// <summary> /// 捕获到非UI线程异常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { if (e.IsTerminating) { log.Error(string.Format("捕获到非UI线程异常,并发生致命错误,导致程序即将终止,请联系运营商!{0}", e.ExceptionObject.ToString())); MessageBox.Show("发生致命错误,导致程序即将终止,请联系运营商!"); } else { log.Error(string.Format("捕获到非UI线程异常 {0}", e.ExceptionObject.ToString())); } }
/// <summary> /// 捕获到Task线程内异常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { log.Exception("捕获到Task线程内异常", e.Exception); e.SetObserved();//设置该异常已察觉(这样处理后就不会引起程序崩溃) }