web-dev-qa-db-ja.com

Application.Exit()とApplication.ExitThread()とEnvironment.Exit()

私はどちらを使用すべきかを理解しようとしています。 WinFormアプリを閉じると、ダイアログモードでフォームが起動します。そのフォームは、DBをリモートDBと同期し、その進行状況を「スプラッシュフォーム」に表示するバックグラウンドワーカーを実行します。

私はそのような方法を持っています:

_private void CloseMyApp()
{
    SaveUserSettings();

    splashForm = new SplashForm();
    splashForm.ShowDialog();

    Application.ExitThread();
    //Application.Exit();
}
_

これは、Menu-> ExitおよびForm_FormClosing()イベントでアプリを閉じるために呼び出すものです。 Application.Exit()は次のエラーを出します->

コレクションが変更されました。列挙操作が実行されない可能性があります。

今、私はEnvironment.Exit()が残忍であり、おそらくあなたのアプリに何か問題があることを意味することを読みました( ここ を参照)。

Application.ExitThread()は機能しますが、機能しているように見えるだけで、通常は使用するのが適切かどうかわからないまで使用したことがないので、私は確信しています。

32

残念ながら、問題はこれらのいずれによっても引き起こされておらず、これらのシナリオのすべてに実際に存在します(メッセージを取得しなくても)。

あなたの問題はこれです:

WinFormアプリを閉じると、ダイアログモードでフォームが起動します。そのフォームは、DBをリモートDBと同期し、その進行状況を「スプラッシュフォーム」に表示するバックグラウンドワーカーを実行します。

シャットダウンを要求したときに実際にシャットダウンしているわけではないため、すべての「Exit」関数がバックグラウンドスレッドを破棄しようとしています。残念ながら、これはおそらくDB同期の途中で発生しており、保存ロジックで動作している列挙がおそらくそのエラーを提供しています。

これらは使用しないことをお勧めします。代わりにmyMainForm.Close()を呼び出してください。これでメインフォームが閉じられ、閉じるロジックが適切に起動されます。アプリケーションのメインフォームが閉じると、正常にシャットダウンします。

24
Reed Copsey

Environment.Exit()は、コンソールアプリに使用されます。

あなたが使いたい:System.Windows.Forms.Application.Exit()

スレッドを終了すると、現在のスレッドコンテキストのみが終了し、開始されたフォアグラウンドスレッドは実行されたままになります。エラーの原因となっているスレッドがまだ実行中であると思われるので、問題を回避するのではなく、本質的に問題をマスクしました。終了時にこのエラー_"Collection was modified; enumeration operation may not execute."_が発生する理由を調べてみます。 Application.Exit()によって公開されていますが、それが原因ではありません。

9
Alan