1

ThreadManagerテスト中に問題なく動作するカスタムを実装しました。ユーザーがアプリケーションを閉じたい場合、すべてのスレッドが終了するか、待機せずにアプリケーションを終了することを選択するまで (30 秒が経過した後)、終了が中断されます。

明確にする必要があるのは、使用がイベントApplication.DoEvents()で危険であるかどうかです。FormClosingそれを使用するか、スレッドが終了するのを待つ別の方法を見つけますか?

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;
}
4

1 に答える 1

3

待機条件を別のスレッドに置くことをお勧めします。OnFormClosing メソッドからモーダル ダイアログを表示します。このダイアログ内で、たとえばBackGroundWorker クラスを使用してワーカー スレッドを開始し、待機が終了したらこのダイアログを閉じます。

おまけトピック Application.DoEvents メソッドの呼び出しで考えられる欠点

于 2012-07-25T10:59:12.630 に答える