延迟应用程序关闭最佳实践?
在用户选择退出 WinForms 程序后,是否有更好的方法来处理执行某些操作的任务:
[编辑 1:响应“NoBugz”的评论 ] 在这种情况下,窗体上没有 ControlBox,并且有理由在用户选择关闭窗体时发生的情况中放置一层间接性[/edit 1]
[edit 2 : 回应截至 20 月 20 日 GMT +7 18:35 的所有评论] 也许使用淡出 MainForm 是一个简单的说明,说明您可能想要执行的操作,因为应用程序是正在关闭:用户无法与之交互:这显然与用户终止应用程序的决定有关。 [/edit 2]
(使用某种形式的线程?)(对多线程应用程序的影响?)(这段代码“味道不好”吗?)
// 'shutDown is an external form-scoped boolean variable
//
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// make sure we don't block Windows ShutDown
// or other valid reasons to close the Form
if (e.CloseReason != CloseReason.ApplicationExitCall) return;
// test for 'shutDown flag set here
if (shutDown) return;
// cancel closing the Form this time through
e.Cancel = true;
// user choice : default = 'Cancel
if (MessageBox.Show("Exit Application ?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.OK)
{
// user says Exit : activate Timer, set the flag to detect Exit
timer1.Enabled = true;
shutDown = true;
}
}
摘要:在一个非常标准的 WinForms 应用程序中(在 Program.cs 中启动的一个 MainForm标准方式):在 MainForm 的 FormClosing 事件处理程序中:
立即退出(触发默认行为:关闭 MainForm 并退出应用程序)如果:
a. CloseReason 是任何其他 CloseReason.ApplicationExitCall
b.如果一个特殊的布尔变量设置为 true,或者
如果没有立即退出:取消对 FormClosing 的“第一次调用”。
用户然后通过 MessageBox.Show 对话框做出选择,退出应用程序,或取消:
a.当然,如果用户取消,应用程序将保持“原样”。
b.如果用户选择“退出”:
将特殊布尔标志变量设置为 true
运行一个执行一些特殊操作的计时器。
当计时器代码中的内部测试检测到“特殊内容”完成时,它会调用 Application.Exit
Is there a better way to handle the task of doing something after the user has chosen to exit a WinForms program than this :
[edit 1 : in response to comment by 'NoBugz] In this case there is no ControlBox on the Form, and there is a reason for putting one level of indirection in what happens when the user chooses to close the Form [/edit 1]
[edit 2 : in response to all comments as of GMT +7 18:35 January 20 ] Perhaps using fading out the MainForm is a simple illustration of what you might want do as the Application is being closed : the user cannot interact with that : it is self-evidently related to the user's decision to terminate the application. [/edit 2]
(use some form of threading ?) (implications for a multi-threaded app ?) (does this code "smell bad" ?)
// 'shutDown is an external form-scoped boolean variable
//
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// make sure we don't block Windows ShutDown
// or other valid reasons to close the Form
if (e.CloseReason != CloseReason.ApplicationExitCall) return;
// test for 'shutDown flag set here
if (shutDown) return;
// cancel closing the Form this time through
e.Cancel = true;
// user choice : default = 'Cancel
if (MessageBox.Show("Exit Application ?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.OK)
{
// user says Exit : activate Timer, set the flag to detect Exit
timer1.Enabled = true;
shutDown = true;
}
}
Summary : In a very standard WinForms application (one MainForm launched in Program.cs in the standard way) : in the FormClosing Event handler of the MainForm :
exit immediately (triggering the default behavior : which is to close the MainForm and exit the Application) if :
a. the CloseReason is anything other CloseReason.ApplicationExitCall
b. if a special boolean variable is set to true, or
if no immediate exit : cancel the "first call" to FormClosing.
the user then makes a choice, via MessageBox.Show dialog, to Exit the Application, or Cancel :
a. if the user Cancels, of course, the Application stays "as is."
b. if the user has chosen to 'Exit :
set the special boolean flag variable to true
run a Timer that does some special stuff.
when the internal test in the Timer code detects the "special stuff" is done, it calls Application.Exit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
作为开发人员和用户,我的建议是:
非常快的任务
速度较慢,但速度也不算太慢的任务
较慢的任务
一些未经测试的示例代码。我们正在我们的一个应用程序中做类似的事情。我们例子中的任务是将窗口属性(位置、大小、窗口状态等)存储到数据库中。
My suggestions, both as a developer and a user:
A very fast task
A less fast, but not incredibly slow task
Slower tasks
Some untested example code. We are doing something similar to this in one of our applications. The task in our case is to store window properties (location, size, window state, et cetera) to a database.
我不认为这有什么“问题”。我唯一的建议是通过在系统托盘上方升起非模式窗口或通知烤面包机,让用户知道程序正在“关闭”。
I don't see anything "wrong" with this. My only recommendation would be to let the user know that the program is "shutting down" by raising a non-modal window or perhaps a notification toaster above the system tray.
几个小要点:
我质疑是否需要计时器:因为应用程序无论如何都会退出,因此用户不会期望 UI 能够响应,为什么不简单地执行清理代码用户界面线程?正如 @Dave Swersky 所建议的,在清理过程中显示一个小通知窗口是有礼貌的。
如果应用程序退出是由 Windows 关闭或用户注销触发的,会发生什么情况?
A couple of minor points:
I'd question the need for a timer: as the application is exiting anyway, and the user won't therefore expect the UI to be responsive, why not simply do the clean-up code on the UI thread? As suggested by @Dave Swersky, a little notification window during cleanup would be polite.
What happens if the application exit is triggered by a Windows shutdown or a user logoff?