C# Note11:如何优雅地退出WPF应用程序
前言
I should know how I am supposed to exit my application when the user clicks on the Exit menu item from the File menu. 或者点击window右上角的X退出应用。
但是退出应用程序时,应该考虑到哪些点呢?
(1)有人认为在关闭应用前,应该触发一个确认窗口,指示用户是否确认退出,因为if there are jobs running, the force exit will cause damages, so we better to let them informed in the confirmation dialog。
(2)有人认为太多的确认是一件非常糟糕的事情。事实上,有人花了点击打开文件菜单,一直向下移动到文件菜单的底部,然后单击退出,几乎确认他们不再希望使用该应用程序。
其实就我来看,上面两类观点都有道理,关键是要适合自己的情况。(This is better to be designed case by case,此话老套而不过时)
如何根据实际情况进行权衡,就是本文要讨论的如何优雅地退出应用程序的问题,只不过这里只针对WPF应用而言。
正文
作为一个程序员,我们先关注下实现exit application的技术。
- 首先,我们可能想到使用:
Application.Current.Shutdown();
(注:Application.Current.Shutdown(); 只能从创建Application对象的线程调用,即通常是主线程)
我做过测试,在MainWindow中,我触发了其他几个windows,然后在MainWindow的window_closed事件中,我添加了该代码,所有的窗口都消失了,但后台程序仍旧在运行。
这是为什么呢?
其实,所有其他owned窗口会被关闭,但你必须确保声明所有权。如果你有一个正在运行的窗口,然后打开另一个窗口但尚未显示,则在关闭活动窗口后,隐藏的窗口将强制应用程序继续运行。除非你通过其他方式(任务管理器等)关闭该窗口,否则将会有潜在的内存泄漏。
另外值得注意的是:Application.Current.Shutdown();是不可逆转的,它通常用于强制应用程序关闭,例如用户注销或关闭Windows时。Instead, 在主窗口中调用this.close(), 这与按“ALT-F4”或窗口上的关闭[x]按钮作用相同。这将导致所有其他所有的窗口关闭,并将最终调用Application.Current.Shutdown();只要关闭动作未被取消。可参阅关闭窗口的MSDN文档。
另外,由于this.close()可以取消,你可以在关闭事件处理程序中放入保存更改确认对话框。只需要构建<Window Closing =“...”>的事件处理程序,并相应地更改e.Cancel的值(true or false)。
- 其次,如果你真的需要关闭应用程序,你也可以使用Environment.Exit(),但它并不优雅(更像是结束进程):
Environment.Exit(0)
Environment.Exit()至少需要一个参数,一个退出代码。如果你不关心退出代码,就像上面那么用。
Environment.Exit is definitely the right way to ensure shutdown of an application. With Application.Current.Shutdown you can easily end up with the application running on indefinitely if you have code that pushes itself back into the dispatcher. 意思就是说这绝对是确保关闭应用的正确方式。使用Application.Current.Shutdown,当你的代码中有回调自身的情况时,很容易出现程序无限运行的结果。
注:与Application.exit(0);同等效果。
代码实例:
MainWindow.xaml中windows部分详情如下:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Application"
mc:Ignorable="d" Title="Application" Height="1050" Width="1800" Closing="Window_Closing" Icon="Images/app_icon.png" Loaded="Window_Loaded">
MainWindow.xaml.cs关键部分:
// Any control that causes the Window.Closing even to trigger.
private void MenuItem_Exit_Click(object sender, RoutedEventArgs e)
{
this.Close();
} // Method to handle the Window.Closing event.
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
MessageBoxResult msgBoxResult = MessageBox.Show("Do you really want to exit?", "Exiting...", MessageBoxButton.YesNo, MessageBoxImage.Exclamation); if (msgBoxResult == MessageBoxResult.No)
{
e.Cancel = true;
return;
}
else
{
var jobState = XXX.GetJobState();
if (jobState == finished || ...)
{
e.Cancel = false;
}
else
{
MessageBox.Show("Application is running job, please wait till finish. ");
e.Cancel = true;
return;
}
} //to do something Uninitialize or ... }
catch (Exception ex)
{
XXX.LogError(appName, ex);
} CloseChildWindows();
} private void CloseChildWindows()
{
if (pythonWindow != null)
{
pythonWindow.Closed -= ChildWindowClosed;
pythonWindow.Close();
pythonWindow = null;
} ......
}
注:该部分一些方法或变量是模拟的。
参考文献:How to exit a WPF app programmatically?
Details on Application.Current
C# Note11:如何优雅地退出WPF应用程序的更多相关文章
- 从nsq中学习如何优雅的退出go 网络程序
退出运行中的程序,可以粗暴的kill -9 $PID,但这样会破坏业务的完整性,有可能一个正在在执行的逻辑半途而费,从而产生不正常的垃圾数据. 本文总结在go语言中,如何能优雅的退出网络应用,涉及的知 ...
- 情景linux--如何优雅地退出telnet
情景linux--在脚本中如何优雅地退出telnet 情景 telnet命令是TELNET协议的用户接口,它支持两种模式:命令模式和会话模式.虽然telnet支持许多命令,但大部分情况下,我们只是使用 ...
- python 如何优雅地退出子进程
python 如何优雅地退出子进程 主进程产生子进程,子进程进入永久循环模式.当主进程要求子进程退出时,如何能安全地退出子进程呢? 参考一些代码,我写了这个例子.运行之后,用kill pid试试.pi ...
- 如何优雅地退出python程序
如何优雅地退出python程序 一个单模的python程序,启动之后要能够优雅地关闭.即当用户按Ctrl+C或者kill pid的时候,程序都能从容关闭.实现起来非常简单. is_running = ...
- 如何优雅的退出/关闭/重启gunicorn进程
在工作中,会发现gunicorn启动的web服务,无论怎么使用kill -9 进程号都是无法杀死gunicorn,经过我一番百度和谷歌,发现想要删除gunicorn进程其实很简单. 1. 寻找mast ...
- 【Golang】程序如何优雅的退出?
1. 背景 项目开发过程中,随着需求的迭代,代码的发布会频繁进行,在发布过程中,如何让程序做到优雅的退出? 为什么需要优雅的退出? 你的 http 服务,监听端口没有关闭,客户的请求发过来了,但处理了 ...
- WPF 之 WPF应用程序事件
当新建一个wpf应用程序,会自动生成一个App.xaml和MainWindow.xaml文件. 其中 App.xam 用来设置Application,应用程序的起始文件和资源及应用程序的一些属性和事件 ...
- 细数改善WPF应用程序性能的10大方法
WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系 ...
- 【C#】1.3 WPF应用程序学习要点
分类:C#.VS2015 创建日期:2016-06-14 使用教材:十二五国家级规划教材<C#程序设计及应用教程>(第3版) 一.要点概述 <C#程序设计及应用教程>(第3版) ...
随机推荐
- 【NOI2018模拟】Yja
[NOI2018模拟]Yja Description 在平面上找\(n\)个点,要求这 \(n\)个点离原点的距离分别为 \(r1,r2,...,rn\) .最大化这\(n\) 个点构成的凸包面积,凸 ...
- JavaScript对象数组根据某属性sort升降序排序
1.自定义一个比较器,其参数为待排序的属性. 2.将带参数的比较器传入sort(). var data = [ {name: "Bruce", age: 23, id: 16 ...
- [ZJOI2012]灾难
嘟嘟嘟 偶尔翻到的一道题. 50分暴力很好想,对于每一个点进行一次拓扑排序,然后每一次别memset,只清空走过的点,能拿到70分. 正解好像也挺好想,是一个叫"灭绝树"的东西. ...
- 001_python单元测试
一.同事推荐的 pytest库 ==> 官网:http://doc.pytest.org/en/latest/ github地址==>https://github.com/pytest-d ...
- Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记
进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...
- sklearn 模型选择和评估
一.模型验证方法如下: 通过交叉验证得分:model_sleection.cross_val_score(estimator,X) 对每个输入数据点产生交叉验证估计:model_selection.c ...
- 算法相关——Java排序算法之插入排序(四)
0. 前言 本系列文章将介绍一些常用的排序算法.排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个" ...
- 深入浅出Tomcat/2 - Tomcat启动和停止
Tomcat启动和停止 很明显,我们启动或停止Tomcat,一般调用的是bin下的startup.sh或shutdown.sh(以Linux为例,以下涉及到平台,若无特殊说明,一般都指Linux).我 ...
- 初步学习Xamarin的感受
一直仰慕Xamarin的大名,最近抽空去浅学了一下. 最后有一种这东西不咋地,又有一种这东西还不错的感觉 先说下为什么不咋地? 如果在公司项目使用Xamarin.forms这个东西.按照国内APP设计 ...
- LeetCode 905. Sort Array By Parity
905. Sort Array By Parity Given an array A of non-negative integers, return an array consisting of a ...