定义一种释放分配的资源的方法。
命名空间: System程序集: mscorlib(在 mscorlib.dll 中)语法
C#
[ComVisibleAttribute(true)] public interface IDisposable
IDisposable 类型公开以下成员。
方法
名称 | 说明 |
执行与释放或重置非托管资源相关的应用程序定义的任务。 |
此接口的主要用途是释放非托管资源。 当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。 但无法预测进行垃圾回收的时间。 另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。
将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。 当不再需要对象时,对象的使用者可以调用此方法。
向现有类添加 IDisposable 接口是重大的更改,因为这更改了类的语义。
重要说明重要事项
C++ 程序员应当阅读 析构函数和终结器在 Visual C++。 在 .NET Framework 版本中,C++ 编译器为实现资源的确定释放提供支持,同时不允许 Dispose 方法的直接实现。
有关如何使用此接口和 Object.Finalize 方法的详细讨论,请参见垃圾回收和实现 Dispose 方法主题。
调用 IDisposable 接口
在调用可实现 IDisposable 接口的类时,请使用 try/finally 模式来确保非托管资源能够释放出来,即使应用程序因出现异常而中断也是如此。
有关 try/finally 模式的更多信息,请参见 Try...Catch...Finally 语句 (Visual Basic)、try-finally(C# 参考)或 try-finally 语句 (C)。
请注意,您可以使用 using 语句(在 Visual Basic 中为 Using)来代替 try/finally 模式。 有关更多信息,请参见 Using 语句 (Visual Basic) 文档或 using 语句(C# 参考) 文档。
示例
下面的示例演示如何创建用来实现 IDisposable 接口的资源类。
C#C++VB
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(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(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(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}