私のすべての読みに基づいて、すべてのファイナライザーを呼び出すための1つのGCスレッドが必要です。ここで問題となるのは、この「1つの」スレッドの範囲です。プロセスごとまたはアプリケーションドメインごとです。ドメインの全体的な目的は、1つのプロセススペースで「独立した」異なるアプリケーションを分離して作成することです。
私はここを読んだ:
ファイナライザーで未処理の例外が発生した場合、CLRの実行スレッドは例外を飲み込み、ファイナライザーを正常に完了したかのように扱い、侵害可能なキューから削除して次のエントリに移動します。
ただし、もっと深刻なのは、ファイナライザーが何らかの理由で終了しない場合、たとえば、ファイナライザーがブロックされ、決して発生しない状態を待機している場合にどうなるかです。この場合、ファイナライザスレッドがハングするため、ファイナライズ可能なオブジェクトがガベージコレクションされることはありません。この状況を十分に認識し、ファイナライザーで管理されていないリソースを解放するための最も単純なコードの記述に固執する必要があります。
もう1つの考慮事項は、アプリケーションのシャットダウン中に何が起こるかです。プログラムがシャットダウンすると、ガベージコレクターは、ファイナライズ可能なすべてのオブジェクトのファイナライザーを呼び出そうとしますが、特定の制限があります。
ファイナライズ可能なオブジェクトは、シャットダウン中に上位のヒープ世代にプロモートされません。
個々のファイナライザーの実行時間は最大2秒です。それより長くかかる場合、それは殺されます。
すべてのファイナライザーが実行されるまでに最大40秒かかります。ファイナライザーがまだ実行中の場合、またはこの時点で保留中の場合、プロセス全体が突然強制終了されます。
「アプリケーション」、「プロセス」、「アプリケーションドメイン」という用語の誤用が多すぎる投稿(および公式ドキュメント)-通常、アプリケーションは単一のプロセスで単一のアプリケーションドメインで実行されるため、それらのほとんどは同等であると想定しています。 。この誤用により、これらのドキュメントはすべて読みにくくなり、役に立たなくなります。
したがって、私の質問では、複数のアプリケーションが、それぞれが単一のプロセスの個別のアプリケーションドメインで実行されることを前提としています。
これらのアプリケーションはすべて同じGCスレッドとファイナライザースレッドを共有していますか?上記の記事で説明されている問題(ファイナライザースレッドのハング)は、そのプロセスのすべてのアプリケーションに影響しますか?はいの場合-ファイナライザースレッドを検出してThread.Abortを送信するなどの回避策(悪いアプリケーションを使用しないこと以外)はありますか?
上記のすべては、私が同様の問題にぶつかったためです。私のアプリケーションは、サードパーティソフトウェア(Outlook)へのアドインとして別のアプリケーションドメインで実行されます。さまざまな理由により、COM参照を完全に解放するためにGC.CollectとGC.WaitForPendingFinalizersを呼び出す必要があります(通常の相互運用ルーチンはOffice / Outlookには不十分です)。特定の他のサードパーティのアドインが実行されていると、GC.WaitForPendingFinalizersが永久にハングします。 、そのため、そのサードパーティに「悪い」ファイナライザーが追加されているのではないかと思います。私はその追加(クライアントの要件)を置き換える/削除することを制御できないので、それらを共存させる方法を自分で理解する必要があります。