IDisposable.Dispose メソッド

定義

アンマネージ リソースの解放またはリセットに関連付けられているアプリケーション定義のタスクを実行します。

public:
 void Dispose();
public void Dispose ();
abstract member Dispose : unit -> unit
Public Sub Dispose ()

次の例は、メソッドを実装する方法を示して Dispose います。

#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;

// The following example demonstrates how to create a class that 
// implements the IDisposable interface and the IDisposable.Dispose
// method with finalization to clean up unmanaged resources. 
//
public ref class MyResource: public IDisposable
{
private:

   // Pointer to an external unmanaged resource.
   IntPtr handle;

   // A managed resource this class uses.
   Component^ component;

   // Track whether Dispose has been called.
   bool disposed;

public:
   // The class constructor.
   MyResource( IntPtr handle, Component^ component )
   {
      this->handle = handle;
      this->component = component;
      disposed = false;
   }

   // This method is called if the user explicitly disposes of the
   // object (by calling the Dispose method in other managed languages, 
   // or the destructor in C++). The compiler emits as a call to 
   // GC::SuppressFinalize( this ) for you, so there is no need to 
   // call it here.
   ~MyResource() 
   {
      // Dispose of managed resources.
      component->~Component();

      // Call C++ finalizer to clean up unmanaged resources.
      this->!MyResource();

      // Mark the class as disposed. This flag allows you to throw an
      // exception if a disposed object is accessed.
      disposed = true;
   }

   // Use interop to call the method necessary to clean up the 
   // unmanaged resource.
   //
   [System::Runtime::InteropServices::DllImport("Kernel32")]
   static Boolean CloseHandle( IntPtr handle );

   // The C++ finalizer destructor ensures that unmanaged resources get
   // released if the user releases the object without explicitly 
   // disposing of it.
   //
   !MyResource()
   {      
      // Call the appropriate methods to clean up unmanaged 
      // resources here. If disposing is false when Dispose(bool,
      // disposing) is called, only the following code is executed.
      CloseHandle( handle );
      handle = IntPtr::Zero;
   }

};

void main()
{
   // Insert code here to create and use the MyResource object.
   MyResource^ mr = gcnew MyResource((IntPtr) 42, (Component^) gcnew Button());
   mr->~MyResource();
}
using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(disposing: true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SuppressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;
            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(disposing: false) is optimal in terms of
            // readability and maintainability.
            Dispose(disposing: false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}
Imports System.ComponentModel

' The following example demonstrates how to create
' a resource class that implements the IDisposable interface
' and the IDisposable.Dispose method.
Public Class DisposeExample

   ' A class that implements IDisposable.
   ' By implementing IDisposable, you are announcing that
   ' instances of this type allocate scarce resources.
   Public Class MyResource
      Implements IDisposable
      ' Pointer to an external unmanaged resource.
      Private handle As IntPtr
      ' Other managed resource this class uses.
      Private component As component
      ' Track whether Dispose has been called.
      Private disposed As Boolean = False

      ' The class constructor.
      Public Sub New(ByVal handle As IntPtr)
         Me.handle = handle
      End Sub

      ' Implement IDisposable.
      ' Do not make this method virtual.
      ' A derived class should not be able to override this method.
      Public Overloads Sub Dispose() Implements IDisposable.Dispose
         Dispose(disposing:=True)
         ' This object will be cleaned up by the Dispose method.
         ' Therefore, you should call GC.SupressFinalize to
         ' take this object off the finalization queue
         ' and prevent finalization code for this object
         ' from executing a second time.
         GC.SuppressFinalize(Me)
      End Sub

      ' Dispose(bool disposing) executes in two distinct scenarios.
      ' If disposing equals true, the method has been called directly
      ' or indirectly by a user's code. Managed and unmanaged resources
      ' can be disposed.
      ' If disposing equals false, the method has been called by the
      ' runtime from inside the finalizer and you should not reference
      ' other objects. Only unmanaged resources can be disposed.
      Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
         ' Check to see if Dispose has already been called.
         If Not Me.disposed Then
            ' If disposing equals true, dispose all managed
            ' and unmanaged resources.
            If disposing Then
               ' Dispose managed resources.
               component.Dispose()
            End If

            ' Call the appropriate methods to clean up
            ' unmanaged resources here.
            ' If disposing is false,
            ' only the following code is executed.
            CloseHandle(handle)
            handle = IntPtr.Zero

            ' Note disposing has been done.
            disposed = True

         End If
      End Sub

      ' Use interop to call the method necessary
      ' to clean up the unmanaged resource.
      <System.Runtime.InteropServices.DllImport("Kernel32")> _
      Private Shared Function CloseHandle(ByVal handle As IntPtr) As [Boolean]
      End Function

      ' This finalizer will run only if the Dispose method
      ' does not get called.
      ' It gives your base class the opportunity to finalize.
      ' Do not provide finalize methods in types derived from this class.
      Protected Overrides Sub Finalize()
         ' Do not re-create Dispose clean-up code here.
         ' Calling Dispose(disposing:=False) is optimal in terms of
         ' readability and maintainability.
         Dispose(disposing:=False)
         MyBase.Finalize()
      End Sub
   End Class

   Public Shared Sub Main()
      ' Insert code here to create
      ' and use the MyResource object.
   End Sub

End Class

注釈

このメソッドを使用して、このインターフェイスを実装するクラスのインスタンスによって保持されているファイル、ストリーム、ハンドルなどのアンマネージリソースを閉じたり解放したりします。 慣例により、このメソッドは、オブジェクトが保持するリソースの解放に関連するすべてのタスク、またはオブジェクトを再利用するための準備に使用されます。

警告

IDisposableインターフェイスを実装するクラスを使用している場合は、クラスの使用が終了したら、そのDispose実装を呼び出す必要があります。 詳細については、「IDisposable 」の「IDisposable を実装するオブジェクトの使用」セクションを参照してください。

このメソッドを実装する場合は、包含階層を介して呼び出しを伝達することによって、保持されているすべてのリソースが解放されるようにします。 たとえば、オブジェクト a がオブジェクト b を割り当て、オブジェクト b がオブジェクト c を割り当てる場合、Dispose実装は b に対してDisposeを呼び出す必要があります。Disposeこの場合、c を呼び出す必要があります。

重要

C++ コンパイラはリソースの決定的な破棄をサポートし、 Disposeメソッドを直接実装することはできません。

基底クラスが IDisposableを実装している場合、オブジェクトはその基底クラスの Disposeメソッドも呼び出す必要があります。 基底クラスとそのサブクラスにIDisposableを実装する方法の詳細については、「IDisposable」の「IDisposable および継承階層」セクションを参照してください。

オブジェクトのDisposeメソッドが 2 回以上呼び出された場合、オブジェクトは、最初の呼び出しの後すべての呼び出しを無視する必要があります。 メソッドが複数回呼び出された場合、オブジェクトは例外をスローしません Dispose 。 リソースが既に破棄されている場合、Dispose以外のインスタンスメソッドはObjectDisposedExceptionをスローする可能性があります。

ユーザーは、割り当てられた状態と解放された状態を示すために、リソースの種類が特定の規則を使用することを期待できます。 この例としては、従来は open または closed と考えられるストリームクラスがあります。 このような規則を持つクラスの実装者は、メソッドを呼び出すなど、カスタマイズされた名前を持つパブリックメソッドを実装することができ Close Dispose ます。

Disposeメソッドを明示的に呼び出す必要があるが、オブジェクトのコンシューマーがDisposeメソッドを呼び出し忘れ、アンマネージリソースが解放されないという危険性は常にあります。 この回避方法は次の 2 とおりあります。

  • マネージリソースをSystem.Runtime.InteropServices.SafeHandleから派生したオブジェクトでラップします。 次に、 Dispose実装は、 System.Runtime.InteropServices.SafeHandleインスタンスの Disposeメソッドを呼び出します。 詳細については、「Object.Finalize」の 「SafeHandle 代替」セクションを参照してください。

  • Disposeが呼び出されない場合にリソースを解放するには、ファイナライザーを実装します。 既定では、ガベージコレクターは、メモリを再利用する前に、オブジェクトのファイナライザーを自動的に呼び出します。 ただし、 Dispose メソッドが呼び出された場合は、通常、ガベージコレクターが破棄されたオブジェクトのファイナライザーを呼び出す必要はありません。 自動終了処理を回避するために、 Dispose実装ではGC.SuppressFinalizeメソッドを呼び出すことができます。

StreamWriterなどの、アンマネージリソースにアクセスするオブジェクトを使用する場合は、 usingステートメントを使用してインスタンスを作成することをお勧めします。 usingステートメントは、それを使用しているコードが完了すると、ストリームを自動的に閉じ、そのオブジェクトに対してDispose を呼び出します。 例については、クラスを参照してください StreamWriter

適用対象

こちらもご覧ください