这篇文章主要为大家详细介绍了WPF中的APP生命周期以及全局异常捕获的相关资料,文中的示例代码讲解详细,对我们学习WPF有一点的帮助,需要的可以了解一下
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();
到此这篇关于详解WPF中的APP生命周期以及全局异常捕获的文章就介绍到这了,更多相关WPF生命周期 全局异常捕获内容请搜索织梦云以前的文章希望大家以后多多支持织梦云!
本文标题为:详解WPF中的APP生命周期以及全局异常捕获
基础教程推荐
- 一个读写csv文件的C#类 2022-11-06
- C#类和结构详解 2023-05-30
- C# List实现行转列的通用方案 2022-11-02
- C# 调用WebService的方法 2023-03-09
- C#控制台实现飞行棋小游戏 2023-04-22
- unity实现动态排行榜 2023-04-27
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C# windows语音识别与朗读实例 2023-04-27
- winform把Office转成PDF文件 2023-06-14
- ZooKeeper的安装及部署教程 2023-01-22