/// <summary> /// Adds global exception handling on all UI threads, non-UI threads, task scheduler threads, and for DataBinding exceptions thrown from DataBinding errors /// </summary> /// <remarks> /// Any WPF application that implements the IWPFGlobalExceptionHandler interface can call this.UseGlobalExceptionHandling() in the constructor and will /// then use this WPFGlobalExceptionHandler to handle all uncaught exceptions; the implementation of the HandleException() and HandleUnrecoverableException() /// methods will specify what the app should do on normal or unrecoverable exceptions /// </remarks> public static void UseGlobalExceptionHandling <App>(this App app) where App : Application, IWPFGlobalExceptionHandler { IWPFGlobalExceptionHandler exceptionHandler = app; try { // handles non-UI thread exceptions thrown; the app terminates after unhandled exceptions are caught here AppDomain.CurrentDomain.UnhandledException += (s, e) => HandleException(exceptionHandler, e.ExceptionObject as Exception, e.IsTerminating); // handles UI dispatcher thread exceptions thrown app.DispatcherUnhandledException += (s, e) => e.Handled = HandleException(exceptionHandler, e.Exception); // handles domain-wide exceptions where a task scheduler is used for asynchronous operations TaskScheduler.UnobservedTaskException += (s, e) => { if (HandleException(exceptionHandler, e.Exception)) { e.SetObserved(); } }; // allows DataBinding errors to throw exceptions, which are then caught by DispatcherUnhandledException DataBindingErrorHandler.ThrowExceptionsWithDataBindingErrors(); } catch (Exception e) { throw new ApplicationException($"Unable to use global exception handling.\n{e.Message}"); } }
private static bool HandleException(IWPFGlobalExceptionHandler exceptionHandler, Exception exception, bool isTerminating = false) { if (isTerminating) { // run the interface-implemented custom handling exceptionHandler.HandleUnrecoverableException(exception); Application.Current.Shutdown(); return(false); } else { // run the interface-implemented custom handling exceptionHandler.HandleException(exception); return(true); } }