it编程 > App开发 > Windows Phone

WPF异常处理详解

250人参与 2024-08-02 Windows Phone



一、wpf异常

1 未捕获异常

正常情况下,开发过程中都会使用try…catch在可能会出现异常的地方去捕获和处理异常。然而实际上开发过程中,由于开发疏忽和一些未知原因,程序中会存在未被处理的异常,当程序运行到此,可能会导致程序崩溃的情况,这样会大大的降低用户的使用体验。对于这种未发现未处理的异常,称之为未捕获异常(unhandledexception)。

2 模拟未捕获异常场景

下面的案例中,就是模拟一个未捕获的异常场景,点击按钮,抛出异常,不使用try…catch 捕获处理。

        private void button_click(object sender, routedeventargs e)
        {
            throw new exception("一个异常!");
        }

在这里插入图片描述
这种由于未捕获异常导致的程序崩溃,从而影响使用者的正常操作,交互上很不友好。此类异常如果需要追溯就必须去查看windows的事件日志,导致查找问题也比较麻烦。
在这里插入图片描述

二、处理未捕获异常

我们虽然不能完全杜绝未捕获异常的产生,但是当其出现的时候,我们应当予以处理,做到尽量不影响使用者的操作。

在wpf应用程序中,各类未处理异常及其处理方式如下:

异常种类处理方式案例说明
ui线程抛的异常使用application.current.dispatcherunhandledexception 事件处理例如点击了用户界面上面的某个控件,然后执行某行代码的时候,遇到了异常;
非ui线程抛的异常使用appdomain.currentdomain.unhandledexception事件处理例如在一个多线程的程序里面,工作线程的代码遇到了异常。
task线程抛的异常使用taskscheduler.unobservedtaskexception事件处理例如在一个多线程的程序里面,工作线程的代码遇到了异常。

1 dispatcherunhandledexception 异常捕获

具体验证代码如下:
在这里插入图片描述
上面测试结果:

2 unhandledexception异常捕获

如何配置legacyunhandledexceptionpolicy 呢?只需要在 app.config 文件的 <runtime> 节点中添加如下代码:

<legacyunhandledexceptionpolicy enabled="1"/>  

具体使用案例如下所示:
在这里插入图片描述
上面测试结果:

3 unobservedtaskexception异常捕获

在这里插入图片描述
上面测试结果:

通过上面的案例中,我们发现在task中发生异常了以后,并不会马上执行unobservedtaskexception 事件内的代码,而是会等一会儿才执行? 这是因为task异常只有在垃圾回收的时候,才会推送到该事件内进行处理。

4 异常捕获的综合使用

如果我们在项目将三类异常的捕获事件,全部定义出来,即可捕获所有的异常事件。

    <stackpanel>
        <button content="测试ui线程异常" width="300" height="50" click="button_click" margin="10"></button>
        <button content="测试thread线程异常" width="300" height="50" click="button_click_1" margin="10"></button>
        <button content="测试task线程异常" width="300" height="50" click="button_click_2" margin="10"></button>
    </stackpanel>
        private void button_click(object sender, routedeventargs e)
        {
            throw new exception("ui线程异常[01]!");
        }

        private void button_click_1(object sender, routedeventargs e)
        {
            new thread(new threadstart(()=> 
            {
                throw new exception("thread多线程异常[02]");
            })).start();
        }

        private void button_click_2(object sender, routedeventargs e)
        {
            task.run(()=> 
            {
                throw new exception("task多线程异常[03]");                
            });
        }
    public partial class app : application
    {
        public app()
        {
            //当应用程序引发但未处理异常时出现,ui线程的异常,无法捕获多线程异常
            application.current.dispatcherunhandledexception += current_dispatcherunhandledexception;
            
            //当某个异常未被捕获时出现
            appdomain.currentdomain.unhandledexception += currentdomain_unhandledexception;

            //未被观察到的task多线程异常
            taskscheduler.unobservedtaskexception += taskscheduler_unobservedtaskexception;
        }

        private void current_dispatcherunhandledexception(object sender, system.windows.threading.dispatcherunhandledexceptioneventargs e)
        {
            e.handled = true;
            messagebox.show($"current_dispatcherunhandledexception:" + e.exception.message);
        }
        private void currentdomain_unhandledexception(object sender, unhandledexceptioneventargs e)
        {
            messagebox.show($"currentdomain_unhandledexception:" + (e.exceptionobject as exception).message);
        }
        private void taskscheduler_unobservedtaskexception(object sender, unobservedtaskexceptioneventargs e)
        {
            messagebox.show($"taskscheduler_unobservedtaskexception:" + e.exception.message);
        }
    }

结语

以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。


参考资料:
wpf异常处理
taskscheduler.unobservedtaskexception 事件

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

如何解决wpcap.dll丢失? 电脑wpcap.dll文件破损的修复方法

08-01

UE4逆向篇-1_FNamePool

08-01

UE4 虚幻4快捷键教程

08-01

非虚拟机安装Centos7连接wifi并开机自动联网

08-03

Docker下Open WebUI,Ollama的安装实践

08-01

界面控件DevExpress WPF流程图组件,完美复制Visio UI!(二)

08-01

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论