WPF 窗体关闭的方式

1.Close();关闭当前窗口
在WPF应用程序的关闭是有ShutdownMode属性设置,具有3中枚举类型的值:
  1)OnLastWindowClose(默认值)---应用程序最后一个窗体关闭时关闭应用程序
2)OnMainWindowClose---应用程序主窗体关闭时关闭应用程序 3)OnxplicitShutdown---显示调用关闭 这种情况是指当 shutdownMode 值为 0nMainwindowclose 时关闭主窗体,如果有多余线程此方式不适用
2.Application.Current.Shutdown0 只关掉了UI而后台进程没有关掉,直到所有的后台线程结束才算真的结束。 3.Environment.Exit(0) 强制退出,即使有其他的线程没有结束。,不过它不会执行代码块的finally块(如果有的话),但资源清理还是要进行的。它是最常见的退出当前进程的方法之一 4.Process对象实例.Kill() var currentProcess =Process.GetCurrentProcess();
currentProcess.Ki11(); 从名字也可以看出来,直接杀掉,不给喘息喘息机会,Ki方法会直接结束整个进程,不进行常规资源清理(什么finally块等.)
5.Environment类的FailFast:这是最暴力最彻底最直接的方法,它甚至不需要向操作系统返回进程退出代码(ExitCode),
直接结束当前进程并在应用程序事件薄中写入信息,用于程序出现致命错误需要立即停止,一般不建议使用。
<Application
x:Class="WpfApp1.ApPxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local= "clr-namespace:WpfApp"
ShutdownMode="OnMainWindowClose"
StartupUri-"MainWindow.xaml">
</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 @ 2024-08-16 10:46  【君莫笑】  阅读(209)  评论(0编辑  收藏  举报