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