应该同时使用AppDomain.UnhandledException和Application.DispatcherUnhandledException吗? [英] Should use both AppDomain.UnhandledException and Application.DispatcherUnhandledException?

查看:350
本文介绍了应该同时使用AppDomain.UnhandledException和Application.DispatcherUnhandledException吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读一些关于AppDomain.UnhandledException和Application.DispatcherUnhandledException之间的差异的一些很好的帖子,看来我应该处理这两个。这是因为用户可能会从主UI线程(即Application.DispatcherUnhandledException)抛出的异常中恢复。正确吗?



此外,我还应该给用户一个机会继续这两个程序,还是只是Application.DispatcherUnhandledException?



下面的示例代码处理AppDomain.UnhandledException和Application.DispatcherUnhandledException,并且都给用户尝试继续执行的选项。



[谢谢,下面的一些代码从其他答案中解除]



App.xaml

 < Application x:Class =MyProgram.App
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x = http://schemas.microsoft.com/winfx/2006/xaml
Startup =App_StartupUriEventHandler
Exit =App_ExitEventHandler
DispatcherUnhandledException =AppUI_DispatcherUnhandledException>
< Application.Resources>
< /Application.Resources>
< / Application>

App.xaml.cs

  ///< summary> 
///为Appdomain.UnhandledException添加调度程序
///< / summary>
public App()
:base()
{
this.Dispatcher.UnhandledException + = OnDispatcherUnhandledException;
}

///< summary>
///捕获在主UI线程上抛出的未处理的异常,并允许
///选项用于用户继续程序。
///下面的AppDomain.UnhandledException的OnDispatcherUnhandledException方法将处理任何线程抛出的所有其他异常。
///< / summary>
void AppUI_DispatcherUnhandledException(object sender,System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
if(e.Exception == null)
{
Application.Current。关掉();
返回;
}
string errorMessage = string.Format(发生应用程序错误,如果再次出现此错误,应用程序中似乎存在严重的错误,最好关闭它。\\\
\\\
Error :{0} \\\
\\\
Do你想继续吗?\\\
(如果你单击是,你将继续你的工作,如果你点击不应用程序将关闭),e.Exception.Message);
//插入代码以记录异常
if(MessageBox.Show(errorMessage,Application User Interface Error,MessageBoxButton.YesNoCancel,MessageBoxImage.Error)== MessageBoxResult.No)
{
if(MessageBox.Show(WARNING:应用程序将关闭,任何更改将不会被保存!\\\
Do你真的要关闭它吗?,关闭应用程序!,MessageBoxButton.YesNoCancel,MessageBoxImage。警告)== MessageBoxResult.Yes)
{
Application.Current.Shutdown();
}
}
e.Handled = true;
}

///< summary>
///捕获未被主UI线程抛出的未处理的异常。
/// DispatcherUnhandledException的上述AppUI_DispatcherUnhandledException方法只会处理主UI线程抛出的异常。
///此方法捕获的未处理异常通常终止运行时。
///< / summary>
void OnDispatcherUnhandledException(object sender,System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
string errorMessage = string.Format(发生应用程序错误,如果再次出现此错误,应用程序中的严重错误,并且您最好关闭它。\\\
\\\
Error:{0} \\\
\\\
您要继续吗?\\\
(如果您单击是,您将继续工作,如果你点击没有应用程序将关闭),e.Exception.Message);
//插入代码以记录异常
if(MessageBox.Show(errorMessage,Application UnhandledException Error,MessageBoxButton.YesNoCancel,MessageBoxImage.Error)== MessageBoxResult.No)
{
if(MessageBox.Show(WARNING:应用程序将关闭,任何更改都不会被保存!\\\
Do你真的要关闭它吗?,关闭应用程序!,MessageBoxButton.YesNoCancel,MessageBoxImage.Warning )== MessageBoxResult.Yes)
{
Application.Current.Shutdown();
}
}
e.Handled = true;
}


解决方案


  • AppDomain.CurrentDomain.UnhandledException 理论上捕获所有应用程序域的线程的异常。而不是 e.Handled ,如果不希望进程终止,请使用 e.SetObserved()。我发现这是非常不可靠的。


  • Application.Current.DispatcherUnhandledException 捕获所有异常UI线程。这似乎可靠地工作,并将替换UI线程上的 AppDomain.CurrentDomain.UnhandledException 处理程序(优先)。使用 e.Handled = true 来保持应用程序的运行。


  • 为了捕获其他线程的异常在最好的情况下,他们是在自己的线程处理),我发现System.Threading.Tasks.Task(只有.NET 4.0及更高版本)是低维护。使用方法 .ContinueWith(...,TaskContinuationOptions.OnlyOnFaulted)处理任务中的异常。详情请见此处

    b

    After reading some excellent posts about the difference between AppDomain.UnhandledException and Application.DispatcherUnhandledException, it appears that I should be handling both. This is because it is significantly more likely the user can recover from an exception thrown by the main UI thread (i.e., Application.DispatcherUnhandledException). Correct?

    Also, should I also give the user a chance to continue the program for both, or just the Application.DispatcherUnhandledException?

    Example code below handles both AppDomain.UnhandledException and Application.DispatcherUnhandledException, and both give the user the option to try to continue despite the exception.

    [thanks and some of the code below is lifted from other answers]

    App.xaml

    <Application x:Class="MyProgram.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="App_StartupUriEventHandler"
             Exit="App_ExitEventHandler"
             DispatcherUnhandledException="AppUI_DispatcherUnhandledException">
        <Application.Resources>
        </Application.Resources>
    </Application>
    

    App.xaml.cs [redacted]

    /// <summary>
    /// Add dispatcher for Appdomain.UnhandledException
    /// </summary>
    public App()
        : base()
    {
        this.Dispatcher.UnhandledException += OnDispatcherUnhandledException;
    }
    
    /// <summary>
    /// Catch unhandled exceptions thrown on the main UI thread and allow 
    /// option for user to continue program. 
    /// The OnDispatcherUnhandledException method below for AppDomain.UnhandledException will handle all other exceptions thrown by any thread.
    /// </summary>
    void AppUI_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        if (e.Exception == null)
        {
            Application.Current.Shutdown();
            return;
        }
        string errorMessage = string.Format("An application error occurred. If this error occurs again there seems to be a serious bug in the application, and you better close it.\n\nError:{0}\n\nDo you want to continue?\n(if you click Yes you will continue with your work, if you click No the application will close)", e.Exception.Message);
        //insert code to log exception here
        if (MessageBox.Show(errorMessage, "Application User Interface Error", MessageBoxButton.YesNoCancel, MessageBoxImage.Error) == MessageBoxResult.No)
        {
            if (MessageBox.Show("WARNING: The application will close. Any changes will not be saved!\nDo you really want to close it?", "Close the application!", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                Application.Current.Shutdown();
            }
        }
        e.Handled = true;
    }
    
    /// <summary>
    /// Catch unhandled exceptions not thrown by the main UI thread.
    /// The above AppUI_DispatcherUnhandledException method for DispatcherUnhandledException will only handle exceptions thrown by the main UI thread. 
    /// Unhandled exceptions caught by this method typically terminate the runtime.
    /// </summary>
    void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        string errorMessage = string.Format("An application error occurred. If this error occurs again there seems to be a serious bug in the application, and you better close it.\n\nError:{0}\n\nDo you want to continue?\n(if you click Yes you will continue with your work, if you click No the application will close)", e.Exception.Message);
        //insert code to log exception here
        if (MessageBox.Show(errorMessage, "Application UnhandledException Error", MessageBoxButton.YesNoCancel, MessageBoxImage.Error) == MessageBoxResult.No)
        {
            if (MessageBox.Show("WARNING: The application will close. Any changes will not be saved!\nDo you really want to close it?", "Close the application!", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                Application.Current.Shutdown();
            }
        }
        e.Handled = true;
    }
    

    解决方案

    • AppDomain.CurrentDomain.UnhandledException in theory catches all exceptions on all threads of the appdomain. Instead of e.Handled, use e.SetObserved() if you do not want the process to terminate. 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.

    这篇关于应该同时使用AppDomain.UnhandledException和Application.DispatcherUnhandledException吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆