私たちは最終的にこれについてさらに発見しました(しかし、それまでに私のマシンは再構築され、未登録のプロファイルへの Cookie がここに失われました。うまくいけば、この回答を投稿できるようになります)。
さらなる調査により、最終的に役立つことがわかったいくつかのイベントが見つかりました。
System.Windows.Forms.Application.ThreadExit
- メッセージ ループが終了したときに
発生しますSystem.Windows.Forms.Application.ApplicationExit
- すべてのメッセージ ループが終了
したときに発生します -System.AppDomain.CurrentDomain.DomainUnload
デフォルト以外の
System.AppDomain.CurrentDomain.ProcessExit
ドメインが終了したときに発生します - デフォルトのアプリ ドメインが終了した
System.AppDomain.CurrentDomain.UnhandledException
ときに発生します - キャッチされない例外が発生したときに発生し、アプリを終了します。
アプリケーション ドメインがプロセスのデフォルト (最上位) ドメインであるか、サブドメインとして作成されたか (Web サーバー上など) に応じて、特定のアプリ ドメインではDomainUnload
またはイベントのいずれかのみが可能です。ProcessExit
アプリケーションがどちらであるかを認識していない場合 (この例のように)、実際のアンロードを自分自身でキャッチするには、両方にサブスクライブする必要があります。また、UnhandledException
(.NET2.0 の時点では常に致命的です) 他の 2 つのイベントが妨げられる可能性があるため、これは 3 番目のケースとして処理される可能性があります。これら 3 つのイベントは、どの .NET アプリケーションでも機能するはずです。
の実行時間には制限がある (約 4 秒?) という警告があるProcessExit
ため、そのイベント ハンドラーで大規模な「最終」作業を実行できない場合があります。すぐにできるものである必要があります。
イベントはApplication
WinForms アプリケーションにのみ適用されます (ただし、純粋な WPF アプリケーションには適用されない可能性があると思われます)。特定の仮定がある最も基本的な通常の使用法に基づいて命名されているため、命名は誤解を招く可能性があります。 ThreadExit
は、UI スレッドの実際のSystem.Threading.Thread
ものではなくメッセージ ループ ( Application.Run()
))ApplicationExit
に関連し、同様に 1 つ以上の UI スレッド上のアプリケーション フォームのコレクションに関連しています。通常、Application.Run()
スレッドの entry メソッドから呼び出された への呼び出しが戻ると、entry メソッドはすぐに終了し、スレッド自体は終了します。すべての UI スレッドが終了すると、通常、WinForms アプリはすべて完了して終了します。
もう1つの注目すべきイベントはSystem.Windows.Forms.Application.ThreadException
イベントです。Windows メッセージ ループは、メッセージの処理中に発生する例外をキャッチし、このイベントを送信するように構成できます。これらの例外をキャッチすると、メッセージ ループ (およびその UI スレッド) は (現在のメッセージ ハンドラーを中止した後) 実行を継続できます。このイベントのサブスクライバーは、特定のスレッドに対していつでも 1 つしか存在できません (サブスクリプションは以前のサブスクライバーを上書きします)。メッセージ ループに入る前に、フォームを作成してサブスクライブする前に構成する必要があります。このイベントと詳細については、MSDN ヘルプを参照してSystem.Windows.Forms.Applicaton.SetUnhandledExceptionMode()
ください。