博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于未捕获异常的处理(WPF)
阅读量:2240 次
发布时间:2019-05-09

本文共 2500 字,大约阅读时间需要 8 分钟。

转载自:http://www.cnblogs.com/chenxizhang/p/3280947.html

这一篇文章来谈谈对于WPF应用程序开发中的未捕获异常的处理。

首先,我们当然是要求应用程序开发人员,尽可能地在程序可能出现异常的地方都去捕捉异常,使用try…catch的方式。但是总是有一些意外的情况可能会发生,这就导致会出现所谓的“未捕获异常(UnhandledException)”。对于这一类异常,如果我们没有一个合适的策略进行处理,则当其发生的时候,会给用户带来不太好的使用体验。例如下面这样

备注:这个截图是在Windows 8上面做的,其他操作系统看到的界面可能略有不同。

用户看到这个窗口的时候,其实一般只能点击Close the prograrm按钮。也就是说,这种情况下会导致用户无法继续使用这个程序,而且他们还得不到任何具体的消息:到底发生了什么事情了?除非他们去查看Windows的事件日志。(但一般的用户是不太会这个操作的)

查看Windows的事件日志:https://jingyan.baidu.com/article/91f5db1b057fb61c7e05e375.html

我们可以看到在Windows事件日志中,会有两个具体的事件。首先是一个.NET Runtime的事件

然后是一个Application Error的事件

通常来说,这样的用户体验有值得改进的地方。我们虽然不能防止异常的产生,但是当意外发生的时候,我们应该要以更好地方式地通知到用户,或者尽可能地不要影响用户当前的操作。

 

在WPF这种应用程序中,会有两大类未处理异常:一类是在UI线程抛出来的,例如点击了用户界面上面的某个控件,然后执行某个代码的时候,遇到了异常;另一类是非UI线程跑出来的,例如在一个多线程的程序里面,工作线程的代码遇到了异常。

对于UI线程的未处理异常,我们可以通过监控下面这个事件来处理

Application.Current.DispatcherUnhandledException   

一个参考代码如下:

using System;using System.Windows;namespace WpfApplicationExceptionSample{    ///     /// Interaction logic for App.xaml    ///     public partial class App : Application    {        public App()        {            Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;        }        void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)        {            MessageBox.Show("我们很抱歉,当前应用程序遇到一些问题,该操作已经终止,请进行重试,如果问题继续存在,请联系管理员.", "意外的操作", MessageBoxButton.OK, MessageBoxImage.Information);//这里通常需要给用户一些较为友好的提示,并且后续可能的操作            e.Handled = true;//使用这一行代码告诉运行时,该异常被处理了,不再作为UnhandledException抛出了。        }    }}

运行的效果大致如下

 

对于非UI线程抛出的未处理异常,我们需要监控另外一个事件来处理

AppDomain.CurrentDomain.UnhandledException   

一个参考代码如下

using System;using System.Windows;namespace WpfApplicationExceptionSample{    ///     /// Interaction logic for App.xaml    ///     public partial class App : Application    {        public App()        {            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;        }        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)        {            MessageBox.Show("我们很抱歉,当前应用程序遇到一些问题,该操作已经终止,请进行重试,如果问题继续存在,请联系管理员.", "意外的操作", MessageBoxButton.OK, MessageBoxImage.Information);        }    }}

 

令人不解的是,这个事件中没有和前面那个事件一样的e.Handled参数,就是说,虽然这样是可以捕捉到非UI线程的异常,而且也可以进行相应的处理,但是应用程序还是会退出,也就是说这个异常还是被当作是未处理异常继续汇报给Runtime。

为了改进这一点,我们可以通过修改配置文件来实现。

 

这里的legacyUnhandledExceptionPolicy,如果enabled=1的话,用意是使用早期版本的异常处理策略。

你可能感兴趣的文章
Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)
查看>>
深入理解JVM虚拟机1:JVM内存的结构与消失的永久代
查看>>
深入理解JVM虚拟机3:垃圾回收器详解
查看>>
深入理解JVM虚拟机4:Java class介绍与解析实践
查看>>
深入理解JVM虚拟机5:虚拟机字节码执行引擎
查看>>
深入理解JVM虚拟机6:深入理解JVM类加载机制
查看>>
深入了解JVM虚拟机8:Java的编译期优化与运行期优化
查看>>
深入理解JVM虚拟机9:JVM监控工具与诊断实践
查看>>
深入理解JVM虚拟机10:JVM常用参数以及调优实践
查看>>
深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战
查看>>
深入理解JVM虚拟机13:再谈四种引用及GC实践
查看>>
Spring源码剖析1:Spring概述
查看>>
Spring源码剖析2:初探Spring IOC核心流程
查看>>
Spring源码剖析5:JDK和cglib动态代理原理详解
查看>>
Spring源码剖析6:Spring AOP概述
查看>>
【Linux】进程的理解(二)
查看>>
【C++】STL -- Vector容器的用法
查看>>
【Linux】Linux中的0644 和 0755的权限
查看>>
【数据结构】有关二叉树的面试题
查看>>
【Linux】内核态和用户态
查看>>