2011-08-06 16 views
34

可能性の重複:
Will the Garbage Collector call IDisposable.Dispose for me?IDisposable.Dispose()は自動的に呼び出されますか?

私はいくつかのアンマネージリソースを持つクラスを持っています。私のクラスはIDisposableインターフェイスを実装し、Dispose()メソッドでアンマネージリソースを解放します。 Dispose()メソッドに呼び出す必要がありますか、自動的に何とか呼び出されますか?ガベージコレクタはそれをコールしますか?

答えて

44

Dispose()は自動的に呼び出されません。 ファイナライザがある場合は、が自動的に呼び出されます。 IDisposableを実装すると、ガベージコレクタを待機するのではなく、クラスのユーザーが早期にリソースを解放できるようになります。

クライアントには、例外があってもDispose()の自動呼び出しを処理するusingステートメントを使用することをお勧めします。 IDisposable

適切な実装は次のとおりです。

class MyClass : IDisposable 
{ 
    private bool disposed = false; 

    void Dispose() 
    { 
    Dispose(true); 
    GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
    if(!disposed) 
    { 
     if(disposing) 
     { 
     // Manual release of managed resources. 
     } 
     // Release unmanaged resources. 
     disposed = true; 
    } 
    } 

    ~MyClass() { Dispose(false); } 
} 

クラスのユーザーがDispose()を呼び出す場合、クリーンアップは直接行われます。オブジェクトがガベージコレクタによってキャッチされている場合は、Dispose(false)を呼び出してクリーンアップを実行します。ファイナライザ(~MyClassメソッド)から呼び出された場合、管理参照は無効になる可能性があるため、アンマネージリソースのみを解放することができます。

3

あなたは多分構築物に、手動でこのメソッドを呼び出す必要がありますよう

using(var myclass = new MyClass()) 
{ 
    // do something with myclass 
} 

// now 'myclass'is Disposed 
5

あなたはusing文で、あなたのオブジェクトをインスタンス化した場合のコードはusingブロックを終了すると、処分は()あなたのために呼ばれています

using(var myObject = new MyDisposableObject()) 
{ 
    blah(); 
} // Dispose() is called here (or whenever the code exits the block) 

あなたがusingを使用しない場合、それは)明示的に廃棄する(呼び出すことによって、あなたのオブジェクトを処分することができ(呼び出し元のコード)次第です。

また、呼び出し元がDispose()を呼び出さない場合は、MyObjectの実装者がファイナライザのサポートを追加できます。詳細情報here

6

リソースが正しく処理されていることを確認するには、IDisposableを実装し、デストラクタ(ファイナライザ)にDisposeを呼び出す必要があります。

class Foo : IDisposable 
{ 
    private bool m_disposed = false; 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    ~Foo() 
    { 
     Dispose(false); 
    } 

    protected void Dispose(bool disposing) 
    { 
     if (!m_disposed) 
     { 
      if (disposing) 
      { 
       //release managed resources 
      } 
      //release unmanaged resources 

      m_disposed = true; 
     } 
    } 
} 
関連する問題