IDisposable.Dispose 方法

定义

执行与释放或重置非托管资源关联的应用程序定义的任务。

public void 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.
    }
}

注解

使用此方法关闭或释放非托管资源,例如文件、流和实现此接口的类实例持有的句柄。 按照约定,此方法用于与释放对象持有的资源或准备对象以供重用相关的所有任务。

警告

如果使用实现 接口的 IDisposable 类,则应在使用完 类后调用其 Dispose 实现。 有关详细信息,请参阅本主题中的“使用实现 IDisposable 的对象”部分 IDisposable

实现此方法时,请确保通过包含层次结构传播调用来释放所有保留的资源。 例如,如果对象 A 分配对象 B,而对象 B 分配对象 C,则 A 的 Dispose 实现必须对 B 调用 Dispose ,而 B 又必须调用 Dispose C。

重要

C++ 编译器支持资源的确定性处置,不允许直接实现 Dispose 方法。

如果基类实现 , Dispose 则 对象还必须调用其基类的 IDisposable方法。 有关在基类及其子类上实现 IDisposable 的详细信息,请参阅主题中的 IDisposable “IDisposable 和继承层次结构”部分。

如果多次调用对象的 Dispose 方法,则对象必须忽略第一个调用之后的所有调用。 如果多次调用对象 Dispose 的方法,则对象不得引发异常。 当资源已释放时,除 以外的 Dispose 实例方法可能会引发 ObjectDisposedException

用户可能希望资源类型使用特定约定来表示已分配状态与释放状态。 其中一个示例是流类,它们传统上被认为是开放或关闭的。 具有此类约定的类的实现者可以选择实现具有自定义名称(例如 Close)的公共方法,该方法调用该方法 Dispose

Dispose由于必须显式调用 方法,因此始终存在不释放非托管资源的危险,因为对象的使用者无法调用其Dispose方法。 可通过两种方式来避免此问题:

使用访问非托管资源(例如 StreamWriter)的对象时,最好是使用 using 语句创建实例。 语句 using 会自动关闭流,并在使用该对象的代码完成时对 对象调用 Dispose 。 有关示例,请参阅 StreamWriter 类。

适用于

产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

另请参阅