4

終了するためにスレッドでexit(0)(from )への呼び出しを使用する .NET C# / C++ アプリがあります。<stdlib.h>

奇妙な点は、状況によっては、マネージド オブジェクトのファイナライザーが への呼び出しの直後に呼び出されexit、他の状況ではまったく呼び出されないことです。

状況は非常に決定論的です。アプリは、その有効期間中に外部プラグイン dll (アンマネージ C で記述) からいくつかのメソッドを呼び出します。
dll A を使用すると、ファイナライザーが常に呼び出されます。
dll B を使用すると、ファイナライザーは呼び出されません。

exit(0) 呼び出しの場合のファイナライザーの予想される動作は何ですか? (予期され、文書化された動作がある場合)

外部 dll への呼び出しは、プロセスが終了する方法に影響を与える可能性のあるグローバル設定を変更できますか?

4

4 に答える 4

3

Chris Brumme は、プロセスのシャットダウン中にファイナライザーがどのように処理されるかについて話しました。

肝心なのは、シャットダウン時にファイナライザーが実行されていることを保証する方法はほとんどないように思われるということですが、DLL が何をして動作が異なるかはわかりません (おそらく、1 つの DLL が実行していることが原因である可能性があります)。 .NET にファイナライザーを処理する機会を与える DLL_PROCESS_DETACH 処理の何か。

この記事は .NET 1.x 用です。これが .NET 2.0 以降でどの程度変更されたかはわかりません。

于 2009-04-03T13:15:21.163 に答える
3

Jeff Richter の本によると、システムはプロセスのシャットダウン時にファイナライザーを呼び出そうとしますが、このプロセスをカバーするファイナライザーごと (2 秒) と合計ファイナライズ (40 秒) の両方のタイムアウトがあり、その後プロセスは中止されます。(もちろん、正確な時間は今までに変更されている可能性があります。それは 2.0 に適していました)。

実行に 2 秒以上かかるファイナライザーが表示されていませんか? これにより、ファイナライズが停止します。

于 2009-04-03T13:26:20.420 に答える
2

究極的には、これは「軍拡競争」の問題です。誰かが Microsoft にバグを記録し、いくつかの厄介なコードがプロセスを終了させたときにファイナライザーが実行されていないと不平を言いました-そのため、問題は修正されました. その後、他の誰かがバグを記録して、ファイナライザーが実行されないようにプロセスを強制的に即座に終了させる方法がないように思われるため、Microsoft はそれを再度許可する新しい API を追加します。そのため、別の人は、その新しい種類の終了に応答しても常に実行される新しい種類の「クリティカル」ファイナライザーを要求しています...など。

したがって、現在の軍拡競争で誰が勝っているのかに頼るよりも、C++ コードを変更する方がおそらく簡単でしょう。

于 2009-04-03T13:33:31.867 に答える