異常不可避免,全部地方都寫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)); } } }