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 实现必须调用 Dispose B,后者必须反过来调用 Dispose C。
Important
C++ 编译器支持资源确定性处置,不允许直接实现 Dispose 该方法。
如果基类实现Dispose,IDisposable对象还必须调用其基类的方法。 有关在基类及其子类上实现 IDisposable 的详细信息,请参阅主题中的 IDisposable “IDisposable 和继承层次结构”部分。
如果一个对象的 Dispose 方法被调用多次,则该对象必须忽略第一次调用后的所有调用。 如果多次调用对象的 Dispose 方法,则对象不得导致异常。 除了 Dispose 可以引发 ObjectDisposedException 资源已释放以外的实例方法。
用户可能需要资源类型使用特定约定来表示分配的状态与释放状态。 例如,流类传统上被视为打开或关闭。 具有此类约定的类的实现者可以选择使用自定义名称(例如 Close调用 Dispose 该方法)实现公共方法。
Dispose由于必须显式调用该方法,因此始终存在不释放非托管资源的危险,因为对象的使用者无法调用其Dispose方法。 有两种方法可以避免这种情况:
将托管资源包装在派生自 System.Runtime.InteropServices.SafeHandle的对象中。 然后,Dispose实现Dispose将调用实例的方法System.Runtime.InteropServices.SafeHandle。 有关详细信息,请参阅本主题中的 Object.Finalize “SafeHandle 替代项”部分。
实现终结器以在未调用资源时 Dispose 释放资源。 默认情况下,垃圾回收器会在回收对象的内存之前自动调用对象的终结器。 但是,如果 Dispose 调用了该方法,则垃圾回收器通常不需要调用已释放对象的终结器。 为了防止自动完成, Dispose 实现可以调用 GC.SuppressFinalize 该方法。
使用访问非托管资源(例如 a StreamWriter)的对象时,最佳做法是使用 using 语句创建实例。 该 using 语句会在使用该流的代码完成时自动关闭流并调用 Dispose 对象。 有关示例,请参阅该 StreamWriter 类。