延迟申请关闭的最佳实践?(delay Application Close best practice

2019-10-29 17:15发布

有没有更好的方式来处理用户选择退出的WinForms程序比这之后做一些任务:

在这种情况下,有形式没有控制盒 :[编辑1 响应由“NoBugz评论 ],并有用于把一个间接层中,当用户选择关闭窗体[/编辑1]会发生什么原因

[编辑2: 响应所有评论为北京时间18:35的1月20日 ] 也许使用淡出MainForm的是 ,你可能想要做的应用有什么简单的例子被关闭:用户不能与交互:这是不言自明与用户决定终止应用程序。 [/编辑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应用程序(MainForm的一个Program.cs中推出以标准方式):在MainForm中的的FormClosing事件处理程序:

  1. 立即退出(触发默认行为:这是关闭MainForm,然后退出应用程序),如果:

    一种。 该CloseReason是任何其他CloseReason.ApplicationExitCall

    湾 如果一个特殊的布尔变量设置为true,或

  2. 如果不立即退出:取消了“第一个电话”来的FormClosing。

  3. 然后用户做出选择,通过MessageBox.Show对话框,退出应用程序,或取消:

    一种。 如果用户取消,当然,应用程序保持“原样”。

    湾 如果用户已选择了“退出:

    1. 设置特殊布尔标志变量设置为true

    2. 运行一个定时器,做一些特别的东西。

    3. 当计时器代码的内部测试检测“特别的东西”完成后,它会调用Application.Exit

Answer 1:

我的建议,无论是作为一个开发人员和用户:

一个非常快速的任务

  • 只要做到在Closing事件处理程序的任务。

一个不太快,但不能慢得令人难以置信的任务

  • 创建一个非后台线程在Closing事件处理程序任务(所以它不是关闭应用程序退出时)。
  • 让应用程序退出。 表格会自动消失,等等,但这一过程将继续运行,直到任务完成。
  • 不过,别忘了处理异常和这样在工作线程。 并确保如果用户是任务完成之前重新打开应用程序的事情不会崩溃。

较慢的任务

  • 在Closing事件处理程序,打开关闭向下的形式,让窗体本身密切。
  • 不要在关闭向下形式背后的/任务,同时显示一些友好进步和信息。
  • 当任务完成退出程序。

一些未经测试的示例代码。 我们正在做我们的应用与此类似。 在我们的例子任务是窗口的属性(位置,大小,窗口状态,等等)存储到数据库中。

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    // If it wasn't the user who asked for the closing, we just close
    if (e.CloseReason != CloseReason.UserClosing)
        return;

    // If it was the user, we want to make sure he didn't do it by accident
    DialogResult r = MessageBox.Show("Are you sure you want this?", 
                                     "Application is shutting down.",
                                     MessageBoxButtons.YesNo, 
                                     MessageBoxIcon.Question);
    if (r != DialogResult.Yes)
    {
        e.Cancel = true;
        return;
    }
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
    // Start the task
    var thread = new Thread(DoTask)
    {
        IsBackground = false,
        Name = "Closing thread.",
    };
    thread.Start();

    base.OnFormClosed(e);
}

private void DoTask()
{
    // Some task to do here
}


Answer 2:

我没有看到任何“错误”与此有关。 我唯一的建议是让用户知道该程序“关停”通过提高非模态窗口或者是系统托盘上面的通知烤面包机。



Answer 3:

几个小问题的:

  • 我会质疑一个计时器的需要:随着应用程序退出,无论如何,并且用户将不能因此指望用户界面响应,何不干脆做UI线程上清理代码? 正如@戴夫Swersky建议,清理过程中一点点通知窗口会礼貌。

  • 如果应用程序退出由Windows关机或用户注销触发,会发生什么?



文章来源: delay Application Close best practice?