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

http://www.cnblogs.com/liuyueyu/p/4476151.html

百密一疏的Bug很难避免,没有谁能保证,我的程序永远 0 BUG;

突然接手一个很庞大的项目,在项目运行期间会莫名异常结束,异常极难重现,还找不出BUG代码,代码太多了。

这个时候就需要把程序中发生的BUG记录下来,知道哪里BUG了,才好下次更新解决。

把所有代码全部加 try catch ?  那就怀孕了,真的搞大了。

未捕获的异常处理:

一:C# 在 Application 类中提供了 DispatcherUnhandledException 事件,用于处理UI线程上未捕获的异常

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        DispatcherUnhandledException += App_DispatcherUnhandledException;
        base.OnStartup(e);
    }

    void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        //e.Exception   发生的异常
        //e.Handled     是否已处理异常事件
    }
}

但是 DispatcherUnhandledException 捕获不了 非UI线程上发生的异常

二:C# 在 AppDomain 类中提供了 UnhandledException 事件,用于捕获应用程序域中发生的异常

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show("Unhandle");
//MessageBox.Show((e.ExceptionObject == null ? "Null" : e.ExceptionObject.GetType().Name),
    //    "CurrentDomain_UnhandledException:");
}

这样就能捕获应用程序域中发生的异常,当然,包括UI线程和非UI线程异常,如果你有创建应用程序域的需求,创建完成,再绑定下事件即可。

但是AppDomain.UnhandledException 事件没有提供 终止异常,也就是说,异常发生了,你没捕获,这里通知一下,但是该程序结束还得结束。

在这里要特别提到官方封装的 Delegate.BeginInvoke();

"已知:"在异步函数中发生了异常并且没处理:

"求解:"

1.没调用 Delegate.EndInvoke() 函数:

终止执行。 程序不会挂掉,异常丢弃。这是种很隐蔽的BUG,很难发现。

AppDomain.UnhandledException 事件不会通知发生了异常,这里要特别注意。

public void Hello()
{
    World();
    Load();
}

public void World()
{    throw new Exception();}

public void Load()
{
    MessageBox.Show("Suc");
}

var action = new Action(Hello);
action.BeginInvoke(null, null);

像这种示例,如果在World() 方法中发生了异常,线程会立即终止,Load() 函数就不会执行,程序也不会终止。

一个函数没有执行,也许就会导致很严重的异常,还很难发现。

2.调用了 Delegate.EndInvoke() 函数:

异常抛出, 程序挂掉。

AppDomain.UnhandledException 事件会通知发生了异常

这里也许会有个需求,如果我想处理 AppDomain.UnhandledException 事件中的异常怎么办?程序挂了太恶心了。

我们来继续扩展这个框架

解决在非UI线程中访问UI 异常的小方法

/// <summary>
/// 委托 扩展类
/// </summary>
public static class DelegateExtension
{    /// <summary>
    /// 可以被捕获异常的异步调用
    /// </summary>
    /// <param name="dele"></param>
    public static void UnsafeBeginInvoke(this Delegate dele)
    {
        var action = new Action(() =>
        {
            dele.DynamicInvoke();
        });
        action.BeginInvoke(new AsyncCallback((ar) =>
        {
            try
            {
                action.EndInvoke(ar);
            }
            catch (Exception ex)
            {
                App.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    throw ex;
                }));
            }
        }), null);
    }
}

有点不伦不类哈,厄。把异常推送到UI线程上抛出,让Application.DispatcherUnhandledException 事件处理

其它:C# 在 TaskScheduler 类中提供了 UnobservedTaskException 事件,用于捕获 Task 异步异常

求评论,求吐槽,求求你^v^

时间: 2024-11-07 16:05:56

WPF 程序 处理未捕获异常,和程序莫名终止说拜拜的相关文章

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

(一) 前言各位亲爱的午饭童鞋,是不是经常因为自己的程序中出现未层捕获的异常导致程序异常终止而痛苦不已?嗯,是的.. 但是,大家不要怕,今天给大家分享一个东东可以解决大家这种困扰,吼吼! (二) UncaughtExceptionHandler接口这个接口,顾名思义,就是处理程序中没有处理的异常,而且是在系统抛出异常导致程序异常终止之前哦!那么,在Android里面怎么使用呢? (三) 怎么使用UncaughtExceptionHandler1. 首先,咱们得创建一个UncaughtExcept

未捕获异常,现实程序崩溃闪退

碰到程序崩溃时,闪退效果,不会提示"xxx程序异常,退出程序".这样的效果就要使用到未捕获异常来实现,这里记录了我的一个写法.其实原理很简单,设置程序的未捕获异常监听,实现监听的一个方法,在该方法中现实直接没有提示的退出程序. 捕获异常工具类 package com.tdh.http; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.Thread.UncaughtExceptionHan

WPF 10天修炼 - Application全局应用程序类

Application对象 当一个WPF应用程序启动时,首先会实例化一个全局唯一的Application对象,类似于WinForm下的Application类,用于控制整个应用程序,该类将用于追踪应用程序打开的窗口.在应用程序打开或关闭的时候能够触发相应的事件. 创建Application对象 手动创建Application应用程序对象过程: 1.  使用VS创建WPF应用程序,命名为WPFDemo.然后手动清除App.xaml文件. 2.  添加Startup.cs类,并添加程序代码.如下:

史上最坑的证书报错解决方法:Code=3000 &quot;未找到应用程序的“aps-environment”的权利字符串&quot;

在ios注册远程通知获取设备令牌token的时候 // 注册远程通知获取设备令牌 toKen [[ UIApplication sharedApplication ] registerForRemoteNotificationTypes :(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert )]; 莫名奇妙的总是会走这个错误的委托 // 远程通知注册失败委托 -

使用ADO连接oracle数据库“未找到提供程序。该程序可能未正确安装”解决方案

问题描述:VS2010开发的C++程序,在一台Win7旗舰版的已安装Oracle客户端的PC上连接不上Oracle,提示"未找到提供程序.该程序可能未正确安装",其他语言编写的程序比如C#是可以成功连接Oracle的: 解决办法:首先是找谷歌度娘帮忙,找了几篇文章,都说是没有Oracle的Oledb驱动,去安装目录XXXX\bin下还真没找到OraOLEDB*.dll,然后按照文章帮助将OraOLEDB10.dll文件拷贝至有问题的Win7上,在DOS下开始注册,这时却提示"

ADODB.Connection 错误 &#39;800a0e7a&#39; 未找到提供程序。该程序可能未正确安装。解决方法!

[问题描述]调试基于ACCESS+ASP的网站程序的时候,遇到如下错误: ADODB.Connection 错误 '800a0e7a' 未找到提供程序.该程序可能未正确安装. /Inc/Function.asp,行 9 [原因分析]因为系统是64位的win7或win8.1所以会出现这个问题,解决方法如下: [解决方法]找到IIS应用程序池,“设置应用程序池默认属性”-->“常规”-->”启用 32 位应用程序”,设置为 True即可解决. ADODB.Connection 错误 '800a0e

未找到具有固定名称&ldquo;System.Data.SQLite&rdquo;的 ADO.NET 提供程序的实体框架提供程序

用户代码未处理 System.InvalidOperationException   HResult=-2146233079   Message=未找到具有固定名称"System.Data.SQLite"的 ADO.NET 提供程序的实体框架提供程序.请确保在应用程序配置文件的"entityFramework"节中注册了该提供程序.有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=260882.   Source=E

Error Domain=NSCocoaErrorDomain Code=3000 &quot;未找到应用程序的“aps-environment”的授权字符串&quot; UserInfo=0x17426e940 {NS

注册远程通知是报错 Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的"aps-environment"的授权字符串" UserInfo=0x17426e940 {NSLocalizedDescription=未找到应用程序的"aps-environment"的授权字符串} 1. 在X-code中更新证书: Xcode > Preferences > Accounts > pi

WCF项目问题2-无法激活服务,因为它需要 ASP.NET 兼容性。没有未此应用程序启用 ASP.NET 兼容性。请在 web.config 中启用 ASP.NET 兼容性,或将 AspNetCompatibilityRequirementsAttribute.AspNetCompatibilityRequirementsMode 属性设置为 Required 以外的值。

无法激活服务,因为它需要 ASP.NET 兼容性.没有未此应用程序启用 ASP.NET 兼容性.请在 web.config 中启用 ASP.NET 兼容性,或将 AspNetCompatibilityRequirementsAttribute.AspNetCompatibilityRequirementsMode 属性设置为 Required 以外的值. 在web.config中添加 aspNetCompatibilityEnabled="true"属性即可,如下: <servi