IDisposable.Dispose メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
アンマネージド リソースの解放、解放、またはリセットに関連付けられているアプリケーション定義のタスクを実行します。
public:
void Dispose();
public void Dispose();
abstract member Dispose : unit -> unit
Public Sub Dispose ()
例
次の例は、 Dispose メソッドを実装する方法を示しています。
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# finalizer syntax for finalization code.
// 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 finalizer 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.
}
}
// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.
open System
open System.ComponentModel
open System.Runtime.InteropServices
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[<DllImport "Kernel32">]
extern Boolean CloseHandle(nativeint handle)
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
type MyResource(handle: nativeint) =
// Pointer to an external unmanaged resource.
let mutable handle = handle
// Other managed resource this class uses.
let comp = new Component()
// Track whether Dispose has been called.
let mutable disposed = false
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
interface IDisposable with
member this.Dispose() =
this.Dispose 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.
abstract Dispose: bool -> unit
override _.Dispose(disposing) =
// Check to see if Dispose has already been called.
if not disposed then
// If disposing equals true, dispose all managed
// and unmanaged resources.
if disposing then
// Dispose managed resources.
comp.Dispose()
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle handle |> ignore
handle <- IntPtr.Zero
// Note disposing has been done.
disposed <- true
// 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 finalizer in types derived from this class.
override this.Finalize() =
// Do not re-create Dispose clean-up code here.
// Calling Dispose(disposing: false) is optimal in terms of
// readability and maintainability.
this.Dispose false
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
注釈
このメソッドを使用して、このインターフェイスを実装するクラスのインスタンスによって保持されているファイル、ストリーム、ハンドルなどのアンマネージ リソースを閉じるか解放します。 慣例により、このメソッドは、オブジェクトによって保持されているリソースの解放または再利用のためのオブジェクトの準備に関連するすべてのタスクに使用されます。
Warning
IDisposable インターフェイスを実装するクラスを使用している場合は、クラスの使用が完了したら、そのDispose実装を呼び出す必要があります。 詳細については、 IDisposable トピックの「IDisposable を実装するオブジェクトの使用」セクションを参照してください。
このメソッドを実装する場合は、コンテインメント階層を介して呼び出しを伝達することで、保持されているすべてのリソースが解放されるようにします。 たとえば、オブジェクト A がオブジェクト B を割り当て、オブジェクト B がオブジェクト C を割り当てる場合、A の Dispose 実装は B で Dispose を呼び出す必要があり、C では Dispose を呼び出す必要があります。
Important
C++ コンパイラでは、リソースの確定的な破棄がサポートされており、 Dispose メソッドを直接実装することはできません。
基底クラスがDisposeを実装する場合は、その基底クラスの IDisposable メソッドも呼び出す必要があります。 基底クラスとそのサブクラスに IDisposable を実装する方法の詳細については、 IDisposable トピックの「IDisposable と継承階層」セクションを参照してください。
オブジェクトのDisposeメソッドが 2 回以上呼び出された場合、オブジェクトは、最初の呼び出しの後すべての呼び出しを無視する必要があります。 オブジェクトは、Dispose メソッドが複数回呼び出される場合、例外をスローしてはなりません。 リソースが既に破棄されている場合、 Dispose 以外のインスタンス メソッドは ObjectDisposedException をスローできます。
ユーザーは、リソースの種類で特定の規則を使用して、割り当てられた状態と解放された状態を示す場合があります。 その例として、従来はオープンまたはクローズと考えられているストリーム クラスがあります。 このような規則を持つクラスの実装者は、Close メソッドを呼び出すカスタマイズされた名前 (Dispose など) を持つパブリック メソッドを実装することを選択できます。
Dispose メソッドは明示的に呼び出す必要があるため、オブジェクトのコンシューマーがDispose メソッドの呼び出しに失敗するため、アンマネージド リソースが解放されない危険性が常に存在します。 これを回避するには、次の 2 つの方法があります。
System.Runtime.InteropServices.SafeHandleから派生したオブジェクトでマネージド リソースをラップします。 Dispose実装では、Dispose インスタンスのSystem.Runtime.InteropServices.SafeHandle メソッドが呼び出されます。 詳細については、 Object.Finalize トピックの「SafeHandle の代替方法」セクションを参照してください。
Disposeが呼び出されない場合にリソースを解放するファイナライザーを実装します。 既定では、ガベージ コレクターはメモリを再利用する前にオブジェクトのファイナライザーを自動的に呼び出します。 ただし、 Dispose メソッドが呼び出された場合、通常、ガベージ コレクターが破棄されたオブジェクトのファイナライザーを呼び出す必要はありません。 自動終了を防ぐために、 Dispose 実装は GC.SuppressFinalize メソッドを呼び出すことができます。
StreamWriterなど、アンマネージ リソースにアクセスするオブジェクトを使用する場合は、using ステートメントを使用してインスタンスを作成することをお勧めします。
using ステートメントは、ストリームを自動的に閉じ、使用しているコードが完了したときにオブジェクトのDisposeを呼び出します。 例については、 StreamWriter クラスを参照してください。