[WPF Learning] 4. Handling of unhandled exceptions

Exceptions are inevitable, and it is troublesome to write try ... catch everywhere, so with the handling of unhandled exceptions, there are the following three events:

  1. Application.Current.DispatcherUnhandledException: DispatcherUnhandledException is raised by an Application for each exception that is unhandled by code running on the main UI thread. (Any unhandled exception in the UI thread will trigger this event)
  2. System.Threading.Tasks.TaskScheduler.UnobservedTaskException: Occurs when a faulted task's unobserved exception is about to trigger exception escalation policy (unobserved exceptions in the wrong task will trigger this event). When the Task is garbage collected, the destructor detects that the Task object has an unhandled exception and will throw this exception and trigger it, so it always feels slow.
  3. AppDomain.CurrentDomain.UnhandledException: Unhandled exception of application domain

The first and second events are easy to understand. Both the UI thread and the task thread throw new Excepiton ("test") can be tested. For the third event, it took me a long time to find the place to trigger-for example, in the 1 and 2 events An exception occurred in the method, so you can also understand that the 1 and 2 events have parameters and methods that can be set to processed (e.Handled = True, e.SetObserved ()), the third event is triggered, game over .

Finally, attach my code

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));
        }
    }
}

Guess you like

Origin www.cnblogs.com/moon3/p/12710243.html