异常不可避免,全部地方都写try...catch也麻烦,因此有了未处理异常的处理的东东,分别为如下三个事件:函数
第一、2个事件很好理解,在UI线程和任务线程throw new Excepiton("测试")都能测试出来,第3个事件我是折腾很久才找到触发的地方——好比在一、2事件的方法中又发生了异常,因此也能够理解一、2事件都有参数和方法能够设置成已处理(e.Handled=True、e.SetObserved()),第3个事件一被触发,game over。测试
最后附上个人代码ui
using System; using System.Text; using System.Threading.Tasks; using System.Windows; namespace L3_Exception { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { public App() { Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; } /// <summary> /// 非主线程错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { StringBuilder sb = new StringBuilder(); foreach (Exception item in e.Exception.InnerExceptions) { sb.AppendLine($@"异常类型:{item.GetType()} 异常内容:{item.Message} 来自:{item.Source} {item.StackTrace}"); } e.SetObserved(); Restart("Task Exception", sb.ToString()); } /// <summary> /// App里面的错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { StringBuilder sb = new StringBuilder(); try { Exception ex = e.ExceptionObject as Exception; sb.AppendLine($@"异常类型:{ ex.GetType()} 异常内容:{ ex.Message} 内部异常内容:{ex?.InnerException?.Message} 来自:{ ex.Source} { ex.StackTrace}"); } catch { sb.AppendLine("不可恢复的WPF窗体线程异常"); } Restart("Domain Exception", sb.ToString()); } /// <summary> /// 主线程错误 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { StringBuilder sb = new StringBuilder(); sb.AppendLine($@"异常类型:{ e.Exception.GetType()} 异常内容:{ e.Exception.Message} 内部异常内容:{e.Exception?.InnerException?.Message} 来自:{ e.Exception.Source} { e.Exception.StackTrace}"); e.Handled = true; Restart("主线程异常", sb.ToString()); } private static void Restart(string title, string content) { MessageBox.Show(content, title); //Current.Dispatcher.Invoke(() => Current.Shutdown(-1)); } } }