.NETから安全にCOMオブジェクト参照を解除
-
11-09-2019 - |
質問
私は無事RCWのを解放についてネット上で多くの記事を読みました、そして、誰がどのような順序で行われる必要が正確に何に同意することはできませんので、私はあなたの意見のために人を求めているように私には思えます。例えば、1は、この操作を行うことができます:
object target = null;
try {
// Instantiate and use the target object.
// Assume we know what we are doing: the contents of this try block
// do in fact represent the entire desired lifetime of the COM object,
// and we are releasing all RCWs in reverse order of acquisition.
} finally {
if(target != null) {
Marshal.FinalReleaseComObject(target);
target = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
ただし、一部の人々は、いくつかの後、Marshal.FinalReleaseComObject
前にガベージコレクションを行うことを提唱し、いくつかのすべてではありません。それはすでにそのCOMオブジェクトからデタッチされた、特に後に、手動ですべての単一のRCWをGCに、それは本当に必要ですか?
私の心に、それだけでCOMオブジェクトからRCWを切り離し、自然に期限切れにRCWを残すために簡単かつ容易になるます:
object target = null;
try {
// Same content as above.
} finally {
if(target != null) {
Marshal.FinalReleaseComObject(target);
}
}
これを行うには、それは十分ですか?
解決
がリリースされ、対象のCOMオブジェクトへの参照を持っているあなたのために、それだけでMarshal.FinalReleaseComObject
を呼び出すために十分なの及び好ましいのあるとの のない収集を強制します。言い換えれば、あなたはそれで行われたとすぐにあなたの参照を解放するためにあなたの責任に会いました。私はFinalReleaseComObject
対ReleaseComObject
の問題には触れません。
これは、人々がGC.Collect()
とWaitForPendingFinalizers()
を呼び出す提唱なぜの大きな疑問を残し?
一部の設計のために、それはあなたが安全にReleaseComObject
を呼び出すことはできませんので、これ以上の管理参照がないときを知ることは難しいので。あなたは、2つの選択肢があり、メモリが蓄積し、収集が起こるかコレクトを強制期待してみましょう。
追加のノートがtarget
にnull
を設定すると、通常は不要であるということであり、具体的にあなたのサンプルコードでは不要です。それは参照カウントベースのガベージコレクタを使用していますので、何にオブジェクトを設定すると、VB6のために一般的です。 C#のためのコンパイラはtarget
が最後の使用後に到達不能であるとさえスコープを離れる前に、GC'dすることができることを知っているのに十分(リリース用にビルドするとき)賢いです。そして、最後に使用して、私はあなたがそれをnull
に設定可能性がある場合があるので、最後の使用可能性を意味します。
using System;
class GCTest
{
~GCTest() { Console.WriteLine("Finalized"); }
static void Main()
{
Console.WriteLine("hello");
GCTest x = new GCTest();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("bye");
}
}
あなたが(例えば、CSC GCTest.cs)のリリースをビルドする場合は、は、「ファイナライズ」「こんにちは」と「さようなら」との間でプリントアウトされます。あなたが(例えば、CSC /デバッグGCTest.cs)のデバッグを構築する場合、「ファイナライズ」x
を設定することがCollect()
前には「固定」だろうNULLに一方「さようなら」の後にプリントアウトすることがます。