2011-10-07 14 views
3

私はGCHandle.Alloc(Object)の契約を厳密に理解したいと思います。GCHandle.Alloc(Object)の契約は正確には何ですか?

私が呼び出した場合というのドキュメントから理解

gc.Free(); 

私も場合はfooが収集されますことを理解:

GCHandle gc = GCHandle.Alloc(foo); 

私が呼ぶまでfooはゴミが収集されないことが保証されますAppDomainがアンロードされます。

私がチェックしたいのは、Freeを呼び出さずにAllocへの呼び出しが(ルートの参照として)GCの目では実質的に同じであるかどうかです。

これが正しければ、GCHandle変数gcのスコープはfooの有効期間に影響を与えません。 Freeが呼び出されない場合、AppDomainがアンロードされるまでfooが存続します。

など。 オブジェクトがAllocを呼び出し、GCHandleインスタンスを保持せず、AppDomainがアンロードされるまで存続します。

これは間違いありませんか?

いくつかの参照:

http://msdn.microsoft.com/en-us/library/a95009h1.aspx

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free.aspx

http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx

+0

なぜ誰かがこの行動を利用しようとする気分になるのですか? –

+0

多くは既に持っています。これはシングルトンパターンと呼ばれ、GCHandleを使用する必要はありません。オブジェクトへの静的参照を作成するだけです。参照がクリアされない限り収集されません。 –

+0

@Jim正に、私の理解を明確にすることを正直に頼んでいます - 私はアプリケーションドメインの長いライフサイクルを計画していません(私は代表者がアンマネージドコードのコールバックとしてラップして安全なライフサイクルを見ています。 。 – morechilli

答えて

1

正しいです。 GCHandle変数は、GCHandle.Alloc()に渡すオブジェクトの存続期間に影響を与えません。

class Test 
{ 
    public Test() 
    { 
     System.Runtime.InteropServices.GCHandle.Alloc(this); 
    } 
    ~Test() 
    { 
    } 
} 
class Server : MarshalByRefObject 
{ 
    public Server() 
    { 
     new Test(); 
    } 
    public void Collect() 
    { 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
    } 
} 

そして、次のテストコード:私は、次の2つのクラスでこれを検証し、この例を使用して

AppDomain ad = AppDomain.CreateDomain("test"); 
Server svr = (Server)ad.CreateInstanceAndUnwrap(
    System.Reflection.Assembly.GetExecutingAssembly().FullName, 
    typeof(Server).FullName); 
for (Int32 i = 0; i < 100; i++) 
    svr.Collect(); 

あなたがテストクラスのファイナライザにブレークポイントを設定した場合、あなたはそれがあることに注意しますGC.Collect/WaitForPendingFinalizers呼び出し中には呼び出されません。ただし、appdomainがアンロードされたときにブレークポイントがヒットします。

+0

ありがとう、ありがとう - 私はあなたの例でいくつかのテストを行ったsos.dllを使用して!finalizequeue - これは結論をバックアップ – morechilli

関連する問題