详解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
猜你喜欢
- 前言开发中很多需要javac 的程序依赖 JAVA_HOME环境变量.如果是手工下载源码安装的JDK,很容易知道JAVA_HOME的目录.
- 前言自从用了SpringBoot,个人最喜欢的就是SpringBoot的配置文件了,和Spring比起SpringBoot更加灵活,修改的某
- 在做在线编程题目的时候,需要了解一下数据的输入格式。这样可以对数据处理有比较好的把握,不需要把太多的时间放在这个上面,注重主要的算法逻辑即可
- 1.强引用( Strong Reference )最普遍的引用:Object obj=new Object()抛出OutOfMemoryEr
- 一. Window 分类应用 Window(ApplicationWindow: 对应一个 Acitivity)
- 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很
- AsyncTask什么是AsyncTaskAsyncTask是一个轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和结果传
- 我们都知道java是一种面向对象的编程语言,但是在实际意义上java并不是纯面向对象,因为面向对象的意义就是万物皆对象,那么如果说int类型
- * 的实现使用的模式:代理模式。代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。类似租房的中介。两种 * :(1)jd
- jackson反序列化忽略字段JSON字符串中含有我们并不需要的字段,那么当对应的实体类中不含有该字段时,会抛出一个异常,告诉你有些字段没有
- ContentProvider是内容提供者,可以跨进程提供数据。大家都知道,ContentProvider的启动,是在Application
- 在项目开发中,我们经常会遇到表中的字段名和表对应实体类的属性名称不一定都是完全相同的情况,下面小编给大家演示一下这种情况下的如何解决字段名与
- 一个比较常见的改进用户体验的方案是用Redo/Undo来取代确认对话框,由于这个功能比较常用,本文简单的给了一个在C#中通过Command模
- 一、简单介绍翻看Spring的源码时,发现@Bean注解的源码上标注了Since: 3.0,也就是说,@Bean注解是Spring从3.0版
- 序本文主要研究下在带有lombok(1.16.20版本)注解的代码在java10下的编译问题。问题Fatal error compiling
- 今天记录一下验证码的实现,希望能够帮助到大家!首先我们看一下实现的效果:此验证码的实现没有用到太多的插件,话不多说直接上代码,大家拿过去就可
- 我object != null要避免很多NullPointerException。有什么替代方法:if (someobject != nul
- Spring Data JPA 映射VO/DTO对象在项目开发中,时常需要根据业务需求来映射VO/DTO对象(这两个概念理解感觉很模糊- 。
- 使用开源项目JAVAE 进行视频格式转换JAVAE简介:JAVE (Java音频视频编码器)库是ffmpeg项目的Java包装器。开发人员可
- 实现功能:模拟简单登录功能,登录成功跳转新页面,登录失败在原登录界面提示登录失败信息开发环境:eclipseTomcat-8.0预备知识:H