5

アプリケーションの終了時に、コード ライブラリに通知する必要があります。したがって、System.Window.Forms.Application.ApplicationExit イベントをサブスクライブしました。これは Winforms アプリではうまく機能しますが、コンソール アプリ、サービス、Web アプリ (ASP.NET など) などの他の種類のアプリケーションでも機能しますか? 名前空間はそうではないことを示唆し、Application.Exit()(明示的または暗黙的に) が呼び出されたときに発生する可能性があり、これらの他のケースを呼び出すのは正しくない可能性があります。

これらの他のケースでより良いイベント、またはより普遍的なイベントがありますか (Winforms でも機能する場合)。たとえば、Environment.Exit()(コンソール アプリ) が呼び出されたときのイベントはありますか?

System.Diagnostic.Process で Exited イベントに関する記述を見つけましたが、これは別のプロセスの終了を監視するためのもののようであり、それ自体に関するプロセス (たとえば、Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;) によって受信されたようには見えません。プロセスが実際に終了した後にのみ発生する可能性があるため、機能しないと思います。

これは、特に .NET 2.0 および C# に当てはまります。

4

1 に答える 1

10

私たちは最終的にこれについてさらに発見しました(しかし、それまでに私のマシンは再構築され、未登録のプロファイルへの 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ため、そのイベント ハンドラーで大規模な「最終」作業を実行できない場合があります。すぐにできるものである必要があります。

イベントはApplicationWinForms アプリケーションにのみ適用されます (ただし、純粋な 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()ください。

于 2009-07-20T18:49:31.243 に答える