【问题标题】:Application.DoEvents in FormClosing eventFormClosing 事件中的 Application.DoEvents
【发布时间】:2012-07-25 10:43:46
【问题描述】:

我已经实现了我的自定义ThreadManager,它在我的测试期间一直运行良好。当用户想要关闭应用程序时,关闭会被暂停,直到所有线程退出或者他们选择不等待就结束应用程序(经过 30 秒后)。

我需要澄清的是,如果在 FormClosing 事件中使用 Application.DoEvents() 可能是危险的。我应该使用它还是寻找另一种等待线程退出的方式?

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    // save settings before exit
    Properties.Settings.Default.Save();

    // Update program about intention
    Program.ApplicationClosing = true;

    try
    {
        // Inform user with friendly message
        ShowModalWaitForm("Application is closing.");

        // Keep the timestamp in order to keep track of how much time has passed since form closing started
        DateTime startTime = DateTime.Now;

        // Wait for all threads to die before continuing or ask user to close by force after 30 seconds have passed
        // In case user prefers to wait the timer is refreshed
        int threadsAlive;
        do
        {
            if (_threadManager.TryCountAliveThreads(out threadsAlive) && threadsAlive > 0)
            {
                Application.DoEvents();
                Thread.Sleep(50);
            }

            TimeSpan timePassed = DateTime.Now - startTime;
            if (timePassed.Seconds > 30)
            {
                if (ShouldNotWaitThreadsToExit())
                {
                    break; // Continue with form closing
                }
                else
                {
                    startTime = DateTime.Now; // Wait more for threads to exit
                }
            }
        } while (threadsAlive > 0);
    }
    catch (Exception ex)
    {
        _logger.ErrorException("MainForm_FormClosing", ex);
    }
    finally
    { 
        HideWaitForm(); 
    }
}


private bool ShouldNotWaitThreadsToExit()
{
    return MessageBox.Show(@"Press ""OK"" to close or ""Cancel"" to wait.", "Application not responding ", MessageBoxButtons.OKCancel) == DialogResult;
}

【问题讨论】:

  • 为什么要打扰用户?他们知道发生了什么吗?在我的大多数应用程序中,我只是立即退出应用程序,因为没有理由不这样做。在奇怪的情况下,当我必须确保某些文件已关闭或数据库连接已释放时,我只需最小化应用程序并使用计时器等待“线程关闭”消息或 BeginInvokes() 或其他任何进入。
  • 确实,有一个数据库连接需要释放,还有WebBrowserWatiN 调用需要返回,所以不建议杀死应用程序。最小化与显示等待表单并没有太大区别。

标签: c# multithreading doevents formclosing


【解决方案1】:

我建议将您的等待条件放在另一个线程中。从 OnFormClosing 方法显示一个模式对话框。在此对话框中启动工作线程,例如使用 BackGroundWorker class 并在等待完成时关闭此对话框。

奖金主题 possible drawbacks 调用Application.DoEvents Method

【讨论】:

  • 所以这个,基本上是指e.Cancel = true in FormClosing,对吧? 编辑: 不,它没有。我现在 100% 明白了。
猜你喜欢
  • 2012-04-10
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多