APP生命周期与全局异常捕获

APP生命周期

程序中关闭APP一般使用一下三种方式

// 关闭窗口,当APP里所有窗口都关闭的时候,App执行退出逻辑,执行Exit事件
this.Close();
// 不管有多少窗口打开,退出当前App,执行Exit事件
Application.Current.Shutdown();
// 杀进程,不执行App的Exit事件
System.Environment.Exit(0);
// 线程-》不关闭的情况下    进程无法释放
<Application x:Class="Zhaoxi.EventLesson.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Zhaoxi.EventLesson"
             StartupUri="Window.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

第一种,Window窗体运行在Application中,当窗体关闭时Application内无其他任务就直接结束执行

第二种,直接关闭Application

第三种,直接结束程序进程

APP中提供了程序启动与关闭事件

public partial class App : Application
{
    public App()
    {
        // 生命周期事件   
        this.Startup += App_Startup;
        this.Exit += App_Exit;

        this.SessionEnding += App_SessionEnding;
    }

    private void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
    {
        //操作系统退出的时候触发
        e.Cancel = true;
    }

    private void App_Exit(object sender, ExitEventArgs e)
    {
        // 日志记录    数据保存  缓存    数据库
        Debug.WriteLine("===========App_Exit");
    }

    private void App_Startup(object sender, StartupEventArgs e)
    {
        // 需求   程序运行的时候   exe    传递参数      $  dotnet run  -- -- -- -- ---
        // 业务:更新  更新程序   不允许双击打开       主程序获取更新列表提交到更新程序   
        //throw new NotImplementedException();

        // 业务场景:应用独立启动   不允许多开,可以在这里检查进程   
        //MessageBox.Show(string.Join(",", e.Args));
    }
}

Startup:程序启动时会触发Startup事件,可以利用该事件在程序启动运行时传参

Exit:程序执行结束时会触发Exit事件,可以做临时参数暂存方便下次运行时恢复;使用System.Environment.Exit(0)方式结束程序不会触发Exit事件

SessionEnding:当程序运行时关闭电脑,会在运行中程序列表中显示该进程

DispatcherUnhandledException——UI线程未被处理的异常捕获

从App对象中订阅DispatcherUnhandledException事件

    public partial class App : Application
    {
        public App()
        {
            // Dispatcher   UI线程    未被处理的异常
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
        }
        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message);
        }
    }

 在按钮事件下触发未使用try-catch捕获的异常,会触发DispatcherUnhandledException事件

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //try
            //{
            int i = 0;
            var result = 100 / i;
            //}
            //catch (Exception ex)
            //{

            //}
        }

 AppDomain.CurrentDomain.UnhandledException——非UI线程未被处理的异常捕获

从AppDomain.CurrentDomain对象中订阅UnhandledException事件

    public partial class App : Application
    {
        public App()
        {
            // Dispatcher   UI线程    未被处理的异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // 记录下日志
        }
    }

 在按钮事件下触发Thread线程报错,异常会触发UnhandledException事件

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var thread = new Thread(new ThreadStart(() =>
            {
                int i = 0;
                var result = 100 / i;
            }));
            thread.Start();
            //thread.IsBackground = true;
        }

 TaskScheduler.UnobservedTaskException——未被观察到的Task异常捕获

 从TaskScheduler对象中订阅UnobservedTaskException事件

public partial class App : Application
    {
        public App()
        {
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }
        private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
        {
            
        }
    }

创建两个按钮事件

在按钮1事件下执行Task线程报错,异常会在Task块被GC回收时触发UnobservedTaskException事件

在按钮2事件下执行一次GC回收

private void Button_Click(object sender, RoutedEventArgs e)
        {
           var t= Task.Run(() =>
            {
                int i = 0;
                var result = 100 / i;
            });
        }
        private void Button_Click1(object sender, RoutedEventArgs e)
        {
            GC.Collect();
        }
posted @ 2023-12-04 14:31  ZHIZRL  阅读(15)  评论(0编辑  收藏  举报