Should use both AppDomain.UnhandledException and Application.DispatcherUnhandledException?

风格不统一 提交于 2019-11-29 22:55:37
  • AppDomain.CurrentDomain.UnhandledException in theory catches all exceptions on all threads of the appdomain. I found this to be very unreliable, though.
  • Application.Current.DispatcherUnhandledException catches all exceptions on the UI thread. This seems to work reliably, and will replace the AppDomain.CurrentDomain.UnhandledException handler on the UI thread (takes priority). Use e.Handled = true to keep the application running.

  • For catching exceptions on other threads (in the best case, they are handled on their own thread), I found System.Threading.Tasks.Task (only .NET 4.0 and above) to be low-maintenance. Handle exceptions in tasks with the method .ContinueWith(...,TaskContinuationOptions.OnlyOnFaulted). See my answer here for details.

An AppDomain.UnhandledException handler is wired as:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

But I could not find a way to flag as handled in the handler - so this always seems to result in an app shut down no matter what you do. So I do not think this is a lot of use.

Better to handle Application.Current.DispatcherUnhandledException and to test for CommunicationObjectFaultedException - as you can recover from that by just re-initializing your proxy - exactly as you did at initial connection. E.g:

void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
    if (e.Exception is CommunicationObjectFaultedException) { //|| e.Exception is InvalidOperationException) {
        Reconnect();
        e.Handled = true;
    }
    else {
        MessageBox.Show(string.Format("An unexpected error has occured:\n{0}.\nThe application will close.", e.Exception));
        Application.Current.Shutdown();
    }
}

public bool Reconnect() {
    bool ok = false;
    MessageBoxResult result = MessageBox.Show("The connection to the server has been lost.  Try to reconnect?", "Connection lost", MessageBoxButton.YesNo);
    if (result == MessageBoxResult.Yes)
        ok = Initialize();
    if (!ok)
        Application.Current.Shutdown();
}

where Initialize has your initial proxy instantiation/connection code.

In the code you posted above I suspect that you are handling DispatcherUnhandledException twice - by wiring a handler in xaml AND in code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!