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

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

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

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

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

然后是一个Application Error的事件

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

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

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

Application.Current.DispatcherUnhandledException   http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx

一个参考代码如下:

using System;
using System.Windows; namespace WpfApplicationExceptionSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
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抛出了。
}
}
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

运行的效果大致如下

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

AppDomain.CurrentDomain.UnhandledException  http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

一个参考代码如下

using System;
using System.Windows; namespace WpfApplicationExceptionSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
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);
} }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

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

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

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>

<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

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

关于未捕获异常的处理(WPF)的更多相关文章

  1. WPF 之 未捕获异常的处理

    首先,我们当然是要求应用程序开发人员,尽可能地在程序可能出现异常的地方都去捕捉异常,使用try…catch的方式.但是总是有一些意外的情况可能会发生,这就导致会出现所谓的“未捕获异常(Unhandle ...

  2. APP级别处理未捕获异常

    前言: 项目APP有时候会出现Crash,然后就是弹出系统强制退出的对话框,点击关闭APP. 有的APP进行了处理,会发现,当程序出现异常的时候,会Toast一个提示"程序出现异常,3秒后将 ...

  3. 【转】Winform程序未捕获异常解决方法 EventType clr20r3 P1

    from:http://blog.csdn.net/chichaodechao/article/details/8294922 在开发winform程序时,用到多线程,在服务器部署后运行,老是自动关才 ...

  4. .Net 下未捕获异常的处理

    原地址:http://www.cnblogs.com/eaglet/archive/2009/02/17/1392191.html .Net 下未捕获异常的处理 作者:Eaglet 随着.Net技术的 ...

  5. WPF中Dispatcher未捕获异常之处理

    在UI线程中 在APP.XAML中定义 DispatcherUnhandledException事件 在工作线程中 PageMain.GetInstance().Dispatcher.Invoke(( ...

  6. WPF 程序 处理未捕获异常,和程序莫名终止说拜拜

    http://www.cnblogs.com/liuyueyu/p/4476151.html 百密一疏的Bug很难避免,没有谁能保证,我的程序永远 0 BUG; 突然接手一个很庞大的项目,在项目运行期 ...

  7. Android-小小设置永久解决程序因为未捕获异常而异常终止的问题

    (一) 前言各位亲爱的午饭童鞋,是不是经常因为自己的程序中出现未层捕获的异常导致程序异常终止而痛苦不已?嗯,是的.. 但是,大家不要怕,今天给大家分享一个东东可以解决大家这种困扰,吼吼! (二) Un ...

  8. NUTZ中处理系统未捕获异常

    关键内容 mvc-chain.js ViewProcessor ai.setFailView(“redirect:/sysError.html”); log.error(this.trrowableT ...

  9. WPF捕获全局未处理异常

    在WPF开发过程中我们一般都用try/catch块来捕获异常,但不是每个异常我们都能捕获,程序总会出现一些意想不到情况,抛出一些未捕获的异常,这时就要用到全局异常捕获,即在程序的最外层加上捕获未处理异 ...

随机推荐

  1. maven之上传新的jar包

    今天要求上传若干jar包到maven服务器,师父曾经真的是一步一步点给我看.然后我特喵的忘记了,师父又一步一步点给我看,所以我记录下来,以后留用. 步骤如下,如图所示: 1)先在首页查询下将要上传的j ...

  2. ubuntu使用经验整理

     ===================================================== 清理/boot分区 =================================== ...

  3. 【String与基本类型之间的转换】以及【进制转换】

    1. 基本数据类型---->字符串类型: 方法一:使用连接一个空字符串,例如  基本数据类型+“” : 方法二:静态方法 String.valueOf(),具体有: String.valueOf ...

  4. 如何让MVC6在IIS上面跑

    asp.net5的MVC6发布出来的结果和MVC5之前版本的相差太远了,直接在本地的IIS服务器上面是不可能运行的. 看了汤姆大叔的MVC6项目发布与部署,讲了很多丰富的知识点.但是对于立即要解决问题 ...

  5. [OLE DB 源 [1]] 警告: 无法从 OLE DB 访问接口检索列代码页信息。如果该组件支持“DefaultCodePage”属性,将使用来自该属性的代码页。如果当前的字符串代码页值不正确,请更改该属性的值。如果该组件不支持该属性,将使用来自该组件的区域设置 ID 的代码页。

    SSIS的警告信息,虽然不影响使用,但是对于一个有强迫症的人来说,实在痛苦, 解决办法:控件右键--属性--AlaywayseUseDefaultCodePage 修改成True即可,默认为False

  6. Select for update/lock in share mode 对事务并发性影响

    select for update/lock in share mode 对事务并发性影响 事务并发性理解 事务并发性,粗略的理解就是单位时间内能够执行的事务数量,常见的单位是 TPS( transa ...

  7. java程序保护如何知识产权,特别提供一个java 开发的java 源代码级的混淆器

    java程序保护如何知识产权,特别提供一个java 开发的java 源代码级的混淆器 下载地址:http://yunpan.cn/QXhEcGNYLgwTD 运行方式:java -jar Encryp ...

  8. 开始VS 2012中LightSwitch系列的第4部分:太多信息了!使用查询来排序和筛选数据

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 4: Too much information! Sorting and Filtering Data ...

  9. 即时通信系统中如何实现:全局系统通知,并与Web后台集成?【低调赠送:QQ高仿版GGTalk 5.1 最新源码】

    像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用GGTalk的朋友都建议我加上一个类似 ...

  10. 5天玩转C#并行和多线程编程 —— 第四天 Task进阶

    5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...