详解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

标签:WPF,生命周期,异常,捕获
0
投稿

猜你喜欢

  • C#实现简单的计算器功能

    2021-05-31 01:52:46
  • 聊聊Java Double相加出现的怪事

    2023-07-22 22:46:39
  • SpringCloud Feign转发请求头(防止session失效)的解决方案

    2022-08-29 12:25:59
  • MyBatis Example And与Or混合使用的实例

    2021-11-11 01:53:13
  • C#利用VS中插件打包并发布winfrom程序

    2022-01-01 21:18:22
  • Spring Cloud Zuul集成Swagger实现过程解析

    2021-05-26 12:36:09
  • 基于C#实现乱码视频效果

    2022-01-25 14:29:56
  • SpringCloud-Alibaba-Nacos启动失败解决方案

    2023-12-19 05:34:45
  • 25行Java代码将普通图片转换为字符画图片和文本的实现

    2023-11-24 02:04:26
  • 教你安装配置Android Studio

    2023-07-09 03:26:17
  • java组件SmartUpload和FileUpload实现文件上传功能

    2022-02-02 17:08:17
  • java应用占用内存过高排查的解决方案

    2023-09-21 12:47:30
  • spring mvc中@PathVariable / 带斜杠方式获取

    2022-09-15 04:47:27
  • Java字母加数字组合比较大小

    2023-02-27 15:27:52
  • Android Jetpack库剖析之LiveData组件篇

    2022-08-31 02:08:13
  • Android自定义View实现通讯录字母索引(仿微信通讯录)

    2023-05-14 04:34:22
  • C#控制台程序中使用官方依赖注入的实现

    2021-07-12 15:35:09
  • Android集成百度地图开发流程和注意事项

    2022-03-21 01:56:01
  • Android开发中使用Intent打开第三方应用及验证可用性的方法详解

    2021-08-12 19:28:47
  • C#算法之散列表

    2022-07-30 19:05:52
  • asp之家 软件编程 m.aspxhome.com