WPF global exception capture

Keywords: Windows

Uncaptured exception

In. NET, we use try-catch-final to handle exceptions, but it is difficult to ensure that all exceptions have been caught. Such uncovered exceptions can lead to bug s such as program jamming and data loss.
WPF provides a method to deal with these uncovered exceptions. By registering events, the user-defined operations can be performed on the unprocessed global exception set, thus increasing the stability of the program.

Exceptions on UI threads

For exceptions thrown by code running on UI threads, Application will trigger a Dispatcher Unhandled Exception.
When you have handled the exception yourself and don't want WPF to continue processing the exception, you need to set the Handled property to true. Generally speaking, if you don't want the program to get stuck, you need to set the Handled property to true.

Global exception

For any unhandled exception, an Unhandled Exception is thrown. It also triggers if an exception is not handled in the UI thread.
Starting with. NET Framework 4, a corrupted process status exception will not trigger the event, such as a stack overflow or access conflict. Because by default, the Common Language Runtime (CLR) does not export these exceptions to managed code and does not call try/catch blocks for them.

Unhandled exception in Task

For unhandled exceptions in Task, Application will throw an Unobserved Task Exception exception.

Examples of programs

Add a button to MainWindow

Registration events:

    /// <summary>
    /// Interaction logic of App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            //Handling uncovered UI exceptions
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;

            //Global exception
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
			
			//Handling Uncaptured Exceptions in Task
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }

        private void TaskScheduler_UnobservedTaskException(object sender, 
        												UnobservedTaskExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message, "TaskScheduler_UnobservedTaskException", MessageBoxButtons.OK, MessageBoxIcon.Error);

            //Exceptions are marked as "detected" so that the program does not crash
            e.SetObserved();
        }

        /// <summary>
        /// Handling exceptions to uncovered non-UI threads
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show("something is wrong.", "CurrentDomain_UnhandledException", MessageBoxButtons.OK, MessageBoxIcon.Error);

        }

        /// <summary>
        /// Handling uncovered UI exceptions
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            //Identification exception has been handled
            //
            e.Handled = true;

            MessageBox.Show(e.Exception.Message, "DispatcherUnhandledException", MessageBoxButtons.OK, MessageBoxIcon.Error);

        }


    }
  • Click on the button to throw an exception directly
        private void Btn_Click(object sender, RoutedEventArgs e)
        {
        	//Throw an exception directly
            throw new InvalidOperationException("throw Exception.");

        }

  • Click the button and Dispatcher throws an exception
		private void Btn_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(() => { throw new InvalidOperationException("Dispatcher--throw Exception."); }));

        }

  • Click the button and Thread throws an exception
        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            Thread t = new Thread(() => { throw new InvalidOperationException("Thread--throw Exception."); });

        }

Click on the button and no exception handler is triggered?

  • Task throws an exception by clicking on the button
        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            //Thread t = new Thread(() => { throw new InvalidOperationException("Thread--throw Exception."); });
            Task.Run(() => { throw new InvalidOperationException("Task--throw Exception."); });

        }

Posted by Tobeon on Fri, 30 Aug 2019 03:13:38 -0700