7

RCWを安全にリリースすることについてネット上でたくさんの記事を読んだことがありますが、何をどの順番で行う必要があるのか​​、正確には誰も同意できないようですので、皆様のご意見をお待ちしております。たとえば、次のようにすることができます。

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する必要が本当にありますか?

私の考えでは、RCWをCOMオブジェクトから切り離し、RCWを自然に期限切れにする方が簡単で簡単です。

object target = null;
try {
    // Same content as above.
} finally {
    if(target != null) {
        Marshal.FinalReleaseComObject(target);
    }
}

それで十分ですか?

4

1 に答える 1

12

ターゲット COM オブジェクトへの参照を解放するには、収集を強制せず呼び出すだけで十分であり、推奨されます。言い換えれば、参照が終わったらすぐに参照をリリースするという責任を果たしたということです。vsの問題には触れません。Marshal.FinalReleaseComObjectFinalReleaseComObjectReleaseComObject

これは、なぜ人々が電話GC.Collect()と電話を支持するのかというより大きな問題を残していWaitForPendingFinalizers()ます。

一部の設計では、管理された参照がいつなくなるかを知るのが難しいため、 を安全に呼び出すことができませんReleaseComObject。2 つの選択肢があります。メモリを蓄積させて収集が行われることを期待するか、収集を強制します。[コメントのスティーブン・ヤンセンの反対票を参照]

追加の注意として、targetへの設定nullは通常は不要であり、特にサンプル コードでは不要です。オブジェクトを何も設定しないことは、参照カウント ベースのガベージ コレクターを使用するため、VB6 では一般的な方法です。C# のコンパイラは (リリース用にビルドする場合) 十分に賢くtarget、スコープを離れる前であっても、最後の使用後に到達できず、GC される可能性があることを認識します。また、最後の使用とは、最後に使用できるという意味なので、 に設定する場合があります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) をビルドすると、"Hello" と "bye" の間に "Finalized" と表示されます。デバッグ (例: CSC /debug GCTest.cs) をビルドすると、"Finalized" は "bye" の後に出力されますが、そのx前に null に設定するCollect()と "修正" されます。

于 2009-12-13T18:37:31.610 に答える