详解WPF中的APP生命周期以及全局异常捕获
作者:步、步、为营 发布时间:2022-12-10 11:54:27
APP生命周期
wpf项目目录中有一个App.xaml.cs文件,该文件中App是一个partical类,与之对应的另一partical部分在App.g.i.cs文件中,该文件是在编译的时候WPF自动生成的。程序的入口Main
方法在该文件中定义。
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.1.0")]
public static void Main() {
WpfApp.App app = new WpfApp.App();
app.InitializeComponent();//初始化Xaml
app.Run();//程序运行
}
APP类继承自Application,常见的生命周期事件有以下几个:
Startup
:在调用 Application 对象的 Run 方法时发生Navigating
:在应用程序中的导航器请求新导航时发生(针对Browser类型的应用)LoadCompleted
:在已经加载、分析并开始呈现应用程序中的导航器导航到的内容时发生Navigated
:在已经找到应用程序中的导航器要导航到的内容时发生,尽管此时该内容可能尚未完成加载NavigationFailed
:在应用程序中的导航器在导航到所请求内容时出现错误的情况下发生NavigationProgress
:在由应用程序中的导航器管理的下载过程中定期发生,以提供导航进度信息NavigationStopped
:在调用应用程序中的导航器的 StopLoading 方法时发生,或者当导航器在当前导航正在进行期间请求了一个新导航时发生SessionEnding
:在用户通过注销或关闭操作系统而结束 Windows 会话时发生Activated
:当应用程序成为前台应用程序时发生,App任意一个窗口激活Deactivated
:当应用程序停止作为前台应用程序时发生,App中所有窗口非激活Exit
:在应用程序关闭之前发生(无法像SessionEnding事件进行取消)
对于普通窗体程序,从开始到结束会依次调用如下事件
-----App_Startup
-----App_Navigating
-----App_Activated
-----App_Exit
窗体生命周期事件
在APP运行后,会启动窗体,窗体常用的声明周期事件如下:
SourceInitialized
:操作系统给窗口分配句柄的时候触发,注意WPF窗体里面的控件是没有句柄的ContentRendered
:窗体内容渲染后触发Loaded
:窗体布局加载完成即准备好交互后触发Activated
:窗体激活Deactivated
:窗体失去焦点Closing
:调用关闭窗体时触发,此时可以取消操作Closed
:窗体关闭后
全局异常捕获
对于异常捕获一般使用try-catch语句进行捕获,但是对于全局的异常可以在App中进行捕获。
DispatcherUnhandledException
:在异常由应用程序引发但未进行处理时发生针对UI线程,无法捕获多线程异常AppDomain.CurrentDomain.UnhandledException
:专门捕获所有线程中的异常TaskScheduler.UnobservedTaskException
:专门捕获Task异常
案例:
APP中进行全局异常捕获
public partial class App : Application
{
public App()
{
//在异常由应用程序引发但未进行处理时发生。UI线程
//无法捕获多线程异常
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
//专门捕获所有线程中的异常
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
//专门捕获Task异常
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Debug.WriteLine("-----App_DispatcherUnhandledException--UI线程" + e.Exception.Message);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Debug.WriteLine("-----CurrentDomain_UnhandledException--其他线程" + (e.ExceptionObject as Exception).Message);
}
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
Debug.WriteLine("-----TaskScheduler_UnobservedTaskException--Task测试" + e.Exception.Message);
e.SetObserved();
}
}
窗体中抛异常
public partial class MainWindow : Window
{
int i = 0;
public MainWindow()
{
InitializeComponent();
//1、ui线程异常测试
_ = 1 / i;
//2、其他线程异常测试
new Thread(new ThreadStart(() => { _ = 1 / i; })).Start();
//3、Task异常测试
Task.Run(() =>
{
_ = 1 / i;
});
}
}
异常 | 结果 | 说明 |
---|---|---|
只打开异常1 | -----App_DispatcherUnhandledException--UI线程-----CurrentDomain_UnhandledException--其他线程 | UI线程中的异常DispatcherUnhandledException和AppDomain.CurrentDomain.UnhandledException均能捕获到 |
只打开异常2 | -----CurrentDomain_UnhandledException--其他线程 | 只有AppDomain.CurrentDomain.UnhandledException可以捕获 |
只打开异常3 | -----TaskScheduler_UnobservedTaskException--Task测试 | 只有TaskScheduler.UnobservedTaskException可以捕获到Task异常 |
备注:Task中的异常并不是立刻就能捕获到的,而是等到垃圾回收的时候进行捕获。如果想立刻进行捕获则可以调用GC.Collect(0);
和GC.WaitForPendingFinalizers();
来源:https://www.cnblogs.com/qsnn/p/17068129.html


猜你喜欢
- 本文实例讲述了Android编程之手机壁纸WallPaper设置方法。分享给大家供大家参考,具体如下:/** * Andorid设置手机屏幕
- 本文实例讲述了Android编程实现使用webView打开本地html文件的方法。分享给大家供大家参考,具体如下:在布局的配置文件里:<
- 本文介绍的库中的侧滑效果借鉴自SwipeMenu,并对SipwMenu的源码做了修改与Bug修复,然后才开发出的SwipeRecyclerV
- 首先客户端从服务器端获取json数据1、利用HttpUrlConnection/** &nbs
- 用C#如何生成二维码,我们可以通过现有的第三方dll直接来实现,下面列出几种不同的生成方法:1):通过QrCodeNet(Gma.QrCod
- clone() 方法麻烦一些,需要将所有涉及到的类实现声明式接口 Cloneable,并覆盖Object类中的clone()方法,并设置作用
- 前言自 Java 7 以来,java 中的 switch 语句经历了快速发展。因此,在本文中,我们将通过示例讨论 switch 语句从 ja
- 前言在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,
- 本文实例讲述了Android开发实现的计时器功能。分享给大家供大家参考,具体如下:效果图:布局:三个按钮 加上一个Chronometer&l
- 1、每帧检查定义一个时间变量 timer,每帧将此时间减去帧间隔时间 Time.deltaTime,如果小于或者等于零,说明定时器到了,执行
- 我们有时候会遇到这样的情况,需要获取某些中文的拼音、中文首字母缩写和中文首字母,下面我将为大家介绍一下如何获取中文拼音的缩写。1、项目建立和
- Javaweb分页技术实现分页技术就是通过SQL语句(如下)来获取数据,具体实现看下面代码//分页查询语句select * from 表名
- 继承ClassLoader并且重写findClass方法就可以自定义一个类加载器,具体什么是类加载器以及类加载器的加载过程与顺序下次再说,下
- 抽像类: public abstract class AbUserAll &nbs
- SEATA概要seata 是alibaba 出的一款分布式事务管理器,他有侵入性小,实现简单等特点。我们能够使用seata 实现分布式事务管
- 本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下实现思路:首先说下布局,整个是一个横向的线性
- java文件输出流是一种用于处理原始二进制数据的字节流类。为了将数据写入到文件中,必须将数据转换为字节,并保存到文件。package com
- 有很多同学肯定想学习opencv相关的知识,但是有些情况下每建一次项目都要重新引入下各种文件是不是很苦恼,所以我也面临了这个问题,在网上看到
- namespace ConsoleApplication2 { class Program { static v
- 什么是 Retrofit ?Retrofit是Square开发的一个Android和Java的REST客户端库。这个库非常简单并且具有很多特