导出 (0) 打印
全部展开
此文章由机器翻译。 将光标移到文章的句子上,以查看原文。 更多信息。
译文
原文

IDisposable 接口

为非托管资源释放提供的机制。

命名空间:  System
程序集:  mscorlib(在 mscorlib.dll 中)

[ComVisibleAttribute(true)]
public interface IDisposable

IDisposable 类型公开以下成员。

  名称说明
公共方法由 XNA Framework 提供支持受 可移植类库 支持受 适用于 Windows 应用商店应用的 .NET 支持Dispose执行与释放或重置非托管资源相关的应用程序定义的任务。
页首

此接口的主要用途是释放非托管资源。 当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。 但无法预测进行垃圾回收的时间。 另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。

将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。 当不再需要对象时,对象的使用者可以调用此方法。

警告说明警告

因为它是一项重大更改,请不将 IDisposable 接口添加到现有类。

因为 IDisposable.Dispose 实现由类型的使用者调用时,实例属于自己的资源不再需要,您应将包装在 SafeHandle (建议使用的替代方法) 的托管对象,则应该重写 Object.Finalize 来释放非托管资源,忘记在使用者调用 Dispose条件下。

重要说明重要事项

C++ 程序员应当阅读 析构函数和终结器在 Visual C++ 在 .NET Framework 中,C++ 编译器支持资源的确定性处置,并且不允许直接实现 Dispose 方法。

有关如何使用此接口和 Object.Finalize 方法的详细讨论,请参见垃圾回收实现 Dispose 方法主题。

使用对象实现 IDisposable

才能直接,使用非托管资源需要实现 IDisposable 如果应用程序使用对象实现 IDisposable,不提供 IDisposable 实现。 而,那么,当您使用时完成,应调用对象的 IDisposable.Dispose 实现。 根据编程语言中,可以为此使用以下两种方式之一:

  • 使用一种语言构造 (在 C# 和 Visual Basic 中的 using 语句。

  • 通过切换到实现 IDisposable.Dispose 的调用在 try/catch 块。

说明说明

实现 IDisposable 注释事实和包括调用其 Dispose 实现的提醒类型的文档。

aax125c9.collapse_all(zh-cn,VS.110).gifC# 和 Visual Basic 使用语句

如果所用语言支持构造 (在 C# 和 Visual Basic 中的 using 语句,则可以使用该项目代替显式调用 IDisposable.Dispose 下面的示例使用在定义此方法保留的文件信息和 Word 数中的 WordCount 类。


using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      using (StreamReader sr = new StreamReader(filename)) {
         txt = sr.ReadToEnd();
         sr.Close();
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   


using 语句实际上是方便语法。 在编译时,语言编译器实现 try/catch 块中间语言 (IL)。

有关 using 语句的更多信息,请参见 Using 语句 (Visual Basic)using 语句(C# 参考) 或主题。

aax125c9.collapse_all(zh-cn,VS.110).giftry/catch 块

如果编程语言不支持 using 语句类似的构造在 C# 或 Visual Basic,或者,如果您不希望使用,则可以从调用 trycatch 语句的 finally 块的 IDisposable.Dispose 实现。 下面的示例将 trycatch替换在上例的 using 块/finally 块。


using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      StreamReader sr = null;
      try {
         sr = new StreamReader(filename);
         txt = sr.ReadToEnd();
         sr.Close();
      }
      catch {}
      finally {
         if (sr != null) sr.Dispose();     
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   


有关 try/finally 模式的更多信息,请参见 Try...Catch...Finally 语句 (Visual Basic)try-finally(C# 参考)try-finally 语句 (C)

实现 IDisposable

当类型直接,使用非托管资源应实现 IDisposable 当不再需要类型的实例,使用者调用 IDisposable.Dispose 实现以释放资源。 若要处理它们无法调用 Dispose的情况下,应使用或从 SafeHandle 派生的类包装非托管资源,或者应重写类型引用的 Object.Finalize 方法。 在任何情况下,使用 Dispose 方法执行任何清除在使用非托管资源之后是必需的,例如版本,释放或重置非托管资源。

重要说明重要事项

如果定义使用非托管资源,并且为或可能有一个基类,应配置的子类,应实现 IDisposable.Dispose 方法和提供 Dispose的第二个重载,如下一节所述。

IDisposable 和继承层次结构

带有应当释放的子类的基类必须按以下步骤实现 IDisposable

  • 它应提供一个公共、非虚拟 Dispose() 方法和受保护的虚拟 Dispose(Boolean disposing) 方法。

  • Dispose() 方法必须调用 Dispose(true),应禁止显示性能的终止。

  • 基类型不应包括任何终结器。

以下代码片段为反射类的基配置模式。 假定,类型不重写 Object.Finalize 方法。


using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }
}


如果重写 Object.Finalize 方法,此类应实现以下模式。


using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   ~BaseClass()
   {
      Dispose(false);
   }
}


子类应实现以下可释放模式:

  • 它们必须重写 Dispose(Boolean) 并调用基类 Dispose(Boolean) 实现。

  • 如果需要,他们可以提供终结器。 终结器必须调用 Dispose(false)

注意派生类不实现 IDisposable 接口并不包括无参数的 Dispose 方法。 他们只重写基类的 Dispose(Boolean) 方法。

以下代码片段为反射类派生的 Dispose 模式。 假定,类型不重写 Object.Finalize 方法。


using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }
}


下面的示例演示如何创建用来实现 IDisposable 接口的资源类。


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


.NET Framework

受以下版本支持:4.5.2、4.5.1、4.5、4、3.5、3.0、2.0、1.1、1.0

.NET Framework Client Profile

受以下版本支持:4、3.5 SP1

可移植类库

受以下版本支持:可移植类库

适用于 Windows 应用商店应用的 .NET

受以下版本支持:Windows 8

适用于 Windows Phone 应用的 .NET

受以下版本支持:Windows Phone 8、Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(不支持服务器核心角色), Windows Server 2008 R2(支持带 SP1 或更高版本的服务器核心角色;不支持 Itanium)

.NET Framework 并不是对每个平台的所有版本都提供支持。有关支持的版本的列表,请参阅.NET Framework 系统要求

社区附加资源

添加
显示:
© 2014 Microsoft