2009-12-02 18 views
6

RCWを安全にリリースするために、ネット上で多くの記事を読んできましたが、何がどのような順序で行われる必要があるかについて誰も同意できないようです皆さんの意見を聞いています。いくつかの後、.NETから安全にCOMオブジェクトリファレンスを解放する

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前にガベージコレクションを行うことを提唱し、いくつかのすべてではない:例えば、一つはこれを行うことができます。手動でRCWを手動でGCする必要がありますか?特にCOMオブジェクトから既に切り離されている場合は特に必要ですか?私の心に

、それだけでCOMオブジェクトからRCWを切り離し、自然に期限切れにRCWを残すために簡単かつ容易になる:

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

それはそれを行うのに十分ですか?解放対象のCOMオブジェクトへのあなたの参照を持っている

答えて

12

、それは十分で、ちょうど収集を強制しないMarshal.FinalReleaseComObjectを呼び出すために好ましいです。言い換えれば、完了した時点で参照をリリースする責任があります。私はFinalReleaseComObjectReleaseComObjectの問題に触れません。

これは、人々がなぜGC.Collect()WaitForPendingFinalizers()を呼び出すことを主張するのかという大きな疑問を残していますか?

デザインによっては、管理参照がなくなっていることを知りにくいので、安全にReleaseComObjectに電話をかけることはできません。あなたは2つの選択肢があります。記憶が蓄積し、収集が起こることを望み、収集が強制されます。 [コメントのスティーブン・ジャンセンの下投票の注釈を参照]

さらに注意してください。targetnullの設定は、通常サンプルコードでは不要です。参照カウントに基づくガベージコレクタを使用するため、VB6ではオブジェクトを何も設定しないでください。 C#用のコンパイラは、最後に使用した後にtargetが到達不能であり、スコープから離れる前にGCされる可能性があることを知るために(リリース用にビルドするとき)十分に賢いです。最後に使用すると、最後に使用する可能性があるので、nullに設定する場合があります。あなたは以下のコードを自分のためにこれを見ることができます:あなたが(例えば、CSC GCTest.cs)のリリースを構築する場合

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など)をビルドすると、Collect()より前に「x」をヌルに設定すると「バイナリ」の後に「確定済み」が印刷されます。

+0

優れた詳細な解析、ありがとうTony! –

+0

Downvote:これらの人々はすべて、「GC.Collect」を好む反対者を推奨しています。 [Microsoft Distinguished Engineer](http://blogs.msdn.com/b/cbrumme/archive/2003/04/16/51355)。 aspx)、[Visual Studio Team](http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx)、[上位のSOメンバー](http://stackoverflow.com/a/17131389/1995977) –

+0

@スティーブ:リンクをありがとう。あなたの注意書きへの参照を含めるように答えを更新しました。 –

関連する問題