WPF异常处理详解

总目录


文章目录

  • 总目录
  • 一、WPF异常
    • 1 未捕获异常
    • 2 模拟未捕获异常场景
  • 二、处理未捕获异常
    • 1 DispatcherUnhandledException 异常捕获
    • 2 UnhandledException异常捕获
    • 3 UnobservedTaskException异常捕获
    • 4 异常捕获的综合使用
  • 结语


一、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 异常捕获

  • DispatcherUnhandledException 用于捕获UI线程的异常,对于多线程Thread 和Task 异常不会捕获。
  • 该事件中可以通过设置 e.Handle=true ,表明该异常已被处理,不会造成程序崩溃和退出

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

  • UI线程异常【可以捕获】,通过e.Handle处理,应用程序不会发生崩溃或退出情况
  • Thread多线程异常【无法捕获】,会造成应用程序崩溃或退出
  • Task多线程异常【无法捕获】,但不会造成程序崩溃或退出

2 UnhandledException异常捕获

  • UnhandledException 用于捕获应用程序所有的异常
  • 该事件只管捕获,没有什么e.Handle的设置去处理异常
  • 若想应用程序捕获到异常后不退出或崩溃需要配合legacyUnhandledExceptionPolicy 配置设置实现(作用类似于e.Handle=true)

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

<legacyUnhandledExceptionPolicy enabled="1"/>  

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

  • UI线程异常【可以捕获】,但是应用程序仍会发生崩溃或退出情况
  • Thread多线程异常【可以捕获】,应用程序不会崩溃或退出
  • Task多线程异常【无法捕获】,也不会造成程序崩溃或退出

3 UnobservedTaskException异常捕获

  • UnobservedTaskException 专用于捕获Task 多线程异常
    在这里插入图片描述
    上面测试结果:
  • UI线程异常【无法捕获】,应用程序发生崩溃或退出
  • Thread多线程异常【无法捕获】,应用程序会崩溃或退出
  • Task多线程异常【可以捕获】,由于Task多线程的异常本身也不会让应用程序崩溃或退出,因此我们只需在捕获的事件内处理异常即可

UnobservedTaskException 事件执行的时机?

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

4 异常捕获的综合使用

  • 在xaml中
    <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]");                
            });
        }
  • 在App.xaml.cs的代码中
    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 事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/18746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

又一里程碑,alibaba首推Java技术成长笔记,业内评级“钻石级”

前言 根据数据表明&#xff0c;阿里巴巴已经连续3年获评最受欢迎的中国互联网公司&#xff0c;实际上阿里巴巴无论在科技创新力还是社会创造价值这几个方面&#xff0c;都是具有一定代表里的。在行业内&#xff0c;很多互联网企业也将阿里作为自己的标杆&#xff0c;越来越多的…

【PSO-LSTM】基于PSO优化LSTM网络的电力负荷预测(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

iOS与Android应用开发的对比:如何选择最佳开发平台?

第一章&#xff1a;引言 在移动应用开发领域&#xff0c;iOS和Android是最为流行的操作系统。选择最佳的开发平台可以使开发人员更有效地开发和发布应用程序。本文将分析iOS和Android应用开发的优缺点&#xff0c;并提供一些有关如何选择最佳开发平台的建议。 第二章&#xf…

Kali-linux攻击WordPress和其他应用程序

今天越来越多的企业利用SAAS&#xff08;Software as a Service&#xff09;工具应用在他们的业务中。例如&#xff0c;他们经常使用WordPress作为他们网站的内容管理系统&#xff0c;或者在局域网中使用Drupal框架。从这些应用程序中找到漏洞&#xff0c;是非常有价值的。 为…

《算经》中的百钱买百鸡问题,你会做吗?试下看看(39)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 欢迎和猫妹一起&#xff0c;趣味学Python。 今日主题 你知道我国历史上有个王朝叫北魏吗&#xff1f; 北魏&#xff08;386年—534年&#xff09;&#xff0c;南北朝时期北…

AdaSparse: 自适应稀疏网络的多场景CTR预估建模

▐ 摘要 CTR(Click-through rate)预估一直是推荐/广告领域重要技术之一。近年来&#xff0c;通过统一模型来服务多个场景的预估建模已被证明是一种有效的手段。当前多场景预估技术面临的挑战主要来自两方面&#xff1a;1&#xff09;跨场景泛化能力&#xff1a;尤其对稀疏场景&…

vscode IDE 能用的上的扩展工具功能介绍

记录分享vscode扩展&#xff0c;包括提升开发效率。必备。主题美化。ChatGPT等。 参考 vscode-extensions [Best] 记录分享方式&#xff0c;整理自己用的扩展&#xff0c;还有一键备份和还原方法。 ⭐快速下载和使用扩展 后面会介绍很多vscode扩展.这裡有一个技巧&#xff0c;…

为什么二极管具有单向导通性

大家都知道二极管具有单向导通性&#xff0c;比如一个双极性的信号通过二极管后会变成一个单极性的信号。 为了弄清这个问题先来看一下二极管的构成。 在纯净的硅晶体中掺入五价元素&#xff0c;比如磷&#xff0c;就形成了N型半导体&#xff0c;掺入的五价元素多余的电子很容…

uboot移植Linux-SD驱动代码解析

一、uboot与linux驱动 1.1、uboot本身是裸机程序 (1)狭义的驱动概念是指&#xff1a;操作系统中用来具体操控硬件的代码叫驱动 广义的驱动概念是指&#xff1a;凡是操控硬件的代码都叫驱动 (2)裸机程序中是直接使用寄存器的物理地址来操控硬件的&#xff0c;操作系统中必须通…

实时聊天如何做,让客户眼前一亮(一)

网站上的实时聊天功能应该非常有用&#xff0c;因为它允许客户支持立即帮助用户。在线实时聊天可以快速轻松地访问客户服务部门&#xff0c;而它也代表着企业的门面。 让我们讨论一下如何利用SaleSmartly&#xff08;ss客服&#xff09;在网站中的实时聊天视图如何提供出色的实…

纯前端JS实现文件上传解析渲染页面

AI真的能代替前端吗&#xff1f; 回答&#xff1a;不会完全代替 能用吗&#xff1f;复制到项目中只会报错 爆红 ……他完全不能理解你需要什么JavaScript&#xff08;简称JS&#xff09;是一种轻量级的脚本语言&#xff0c;主要用于在Web页面上添加交互行为。它由三个不同的…

项目环境配置、不知晓问题自己搜索后得到的解答

目录 Anolis OS龙蜥操作系统 Kernel Selection 4.18.0(RHCK) Compatible with RHEL (kernel-4.18.0) 4.19.91(ANCK) Support Anolis OS verified platform (kernel-4.19.91) 这两个内核选择哪个比较好呢&#xff1f; 我的C盘有些满&#xff0c;我该如何删除一些我需要的东西…

家用洗地机哪个好用?家用洗地机分享

洗地机是一种代表现代化清洁的设备&#xff0c;它具有高效、环保、经济、智能等多种特点。洗地机可以为您提供先进的清洁技术和设备&#xff0c;为您的清洁工作提供有力的支持。洗地机可以适应不同场所和建筑物的需求&#xff0c;提高工作效率和卫生形象。因此&#xff0c;选择…

logstash介绍和使用-ELK文章2

官方 Logstash 是免费且开放的服务器端数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的“存储库”中。 下载和文档&#xff1a;https://www.elastic.co/cn/logstash/ docker部署&#xff1a;https://hub.docker.…

Linux中信号的基础知识

信号的概念 Linux操作系统中&#xff0c;信号是一种进程间通信&#xff08;Inter-Process Communication, IPC&#xff09;机制&#xff0c;用于向其他进程发送通知或指示&#xff0c;通常是为了通知特定事件的发生&#xff0c;如程序终止、用户按下特定按键等。信号提供了一种…

在字节跳动做了6年软件测试,4月无情被辞,想给划水的兄弟提个醒

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是6年的工作经验吧。 这6年之间完成了一次…

浅谈springboot启动过程

1. 知识回顾 为了后文方便&#xff0c;我们先来回顾一下spring的一些核心概念。 spring最核心的功能无非是ioc容器&#xff0c;这个容器里管理着各种bean。ioc容器反映在java类上就是spring的核心类ApplicationContext。ApplicationContext有众多的子接口和子类&#xff0c;不…

文旅数字人出圈不断,文旅数字人宣传片制作赋能数字文旅新业态

在文旅产业发展中 数字人的应用越来越广泛 文旅借助数字人浪潮 把传统文化与科技相融合 以Z世代年轻群体所喜爱的方式 推动文旅数字化发展 文旅数字人应用场景——数字人文旅宣传片 可以让数字人作为文旅宣传片主角&#xff0c;串联当地代表性的历史文化地标、现代都市场景…

sensor的感光原理

文章内容来自网络&#xff0c;联系我可以删掉。 目录 CMOS sensor上有什么&#xff1f; 不同像素对应的图像质量&#xff1a; 像点感光原理&#xff1a; Bayer格式变换成RGB格式&#xff1a; CMOS sensor上有什么&#xff1f; CMOS sensor 通常由像敏单元阵列、行驱动器、…

第10章:数据处理增删改

一、插入数据 CREATE TABLE emp1 (id int(11) ,name varchar(15) ,hire_date date ,salary double(10,2) )1.添加一条数据 ①没有指明添加的字段&#xff0c;一定按照顺序添加 insert into emp1 values(1,wang,2000-4-4,5900)②指明添加的字段&#xff08;推荐&#xff09;…