请您说细些,如果有必要请您给写个简短的代码,我看过立即结分。我对此类东西真是迷乎了

解决方案 »

  1.   

    Dispose是接口IDisposable的实现,其实是一个东西。都是指对象销毁。
    ~析构就是对象被销毁的时候要调用的方法
    Close一般来说指数据库关闭连接,或者是流关闭。我对于这些概念也不是很精,以上是我的理解。
      

  2.   

    Dispose是IDisposable接口必须实现的方法,当然你在里面写句骂人的话也没问题,这只是个逻辑上的设计。
    一个class的如果实现了IDisposable接口,可以在某些情况下自动调用它的Dispose方法,比如using(classA a=new classA()){}
    close方法与上面的东西没有任何关系。
      

  3.   

    一些BLOG里有很详细的介绍,搜一搜肯定有的
    基本是方法命名习惯、控制释放托管/非托管资源的问题
      

  4.   

    http://hi.baidu.com/zeratul%5Fbb/blog/item/3d975138cfc8142797ddd858.html
      

  5.   

    1 public class Foo: IDisposable
    2 {
    3     public void Dispose()
    4      {
    5         Dispose(true);
    6         GC.SuppressFinalize(this);
    7      }

    9     protected virtual void Dispose(bool disposing)
    10      {
    11        if (!m_disposed)
    12         {
    13            if (disposing)
    14             {
    15               // Release managed resources
    16             }
    17 
    18            // Release unmanaged resources
    19 
    20             m_disposed = true;
    21         }
    22      }
    23 
    24     ~Foo()
    25      {
    26         Dispose(false);
    27      }
    28 
    29     private bool m_disposed;
    30 }
    31 
    32.NET中用于释放对象资源的接口是IDisposable,但是这个接口的实现还是比较有讲究的,此外还有Finalize和Close两个函数。MSDN建议按照下面的模式实现IDisposable接口:.NET的对象中实际上有两个用于释放资源的函数:Dispose和Finalize。Finalize的目的是用于释放非托管的资源,而Dispose是用于释放所有资源,包括托管的和非托管的。
      

  6.   

    关于释放托管/非托管资源,我还是比较有认识的,“文件句柄、数据库链接、位图、网络链接、COM对象、互斥体”这些都是非托管资源,对吧。
    现在的问题是“Dispose是接口IDisposable的实现,其实是一个东西。都是指对象销毁。 
    ~析构就是对象被销毁的时候要调用的方法”,请问Dispose与~析构,谁先谁后???
      

  7.   

    晕了,照6楼说的,“Dispose和Finalize又成了同级的了???”真的假的?
      

  8.   

    析构,Dispose 销毁对象时释放内存时调用的方法
    因为析构函数时垃圾回收器自动调用的,所以调用的时间不定,也就是说使用析构无法控制其销毁的时间
    c#提供了接口IDisposable,通过这个方法,就可以通过在代码中调用来及时地释放内存.
    通过析构释放内存需要垃圾回收器调用两次,才能销毁对象.对于一些流等操作时,Close表达的意思比Dispose更直观,所以提供了Close函数.
    Close仅仅是调用Dispose,就是说Close和Dispose基本等价(这条是我个人观点)
      

  9.   

    Dispose和Finalize又成了同级的了???”真的假的?  Dispose在编译为IL后,好像就是Finalize
      

  10.   

    闹分荒,瞧这个热闹,一句话,抢啊~

    虽然 .net 有垃圾回收机制(GC), 可自动进行大部分的资源清理工作,但开发人员仍旧应该养成良好的通过手动调用资源清理方法来进行资源回收的习惯, 让对象实现 IDisposable 接口正是 M$ 所推荐的, 该接口的原型为:
        // Summary:
        //     Defines a method to release allocated unmanaged resources.
        [ComVisible(true)]
        public interface IDisposable
        {
            // Summary:
            //     Performs application-defined tasks associated with freeing, releasing, or
            //     resetting unmanaged resources.
            void Dispose();
        }
     注:.net 内部也有传说中的”析构函数“,就是 Finalize(), 该函数由GC自动调用。实现 Dispose 需要注意的是
    1. 如果资源已手动释放过了,就应该通知GC,不要再对该对象执行 Finalize 操作
    2. 确保重复执行 Dispose 时不会出错根据以上规则, 简单的定义一个类 classSample
        public class classSample : IDisposable
        {
            /**//// <summary>
            /// 该对象是否已被销毁过
            /// </summary>
            private bool disposed;        /**//// <summary>
            /// 这就是传说中的 Finalize函数,是不是和C++的析构函数很像?
            /// </summary>
            ~classSample()
            {
                Console.WriteLine("对象被销毁");
                
                Dispose(false);
            }        public void Dispose()
            {
                Console.WriteLine("手动销毁对象");
                Dispose(true);
                //通知GC, 偶已经被销毁过了,可以不用在管偶了
                GC.SuppressFinalize(this);
            }        /**//// <summary>
            /// Dispose
            /// </summary>
            /// <param name="disposing">是否由程序直接调用</param>
            protected void Dispose(bool disposing)
            {
                if (!disposed)
                {
                    if (disposing)
                    {
                        //该函数为手动调用,此处可进行托管资源的清理
                        //比如此类中有一个类型为 DataSet 的变量 dsData
                        //此处可调用该对象的 Dispose 方法来清理托管资源
                        dsData.Dispose();
                    }                //进行非托管资源的清理
                    //非托管的资源主要为一些用 API 打开的文件句柄,设备场景句柄等
                    //该类资源 GC 是无法管理的,只能依靠程序员自已释放
                    //不同的资源, 释放方法不一样
                    
                    //释放文件句柄 (定义API的代码略。)
                    CloseHandle(handle);
                    //释放GDI 中的设备场景 (定义API的代码略。)
                    ReleaseDC(hdc);
                }
                disposed = true;
            }
        }
    注意protected void Dispose(bool disposing) 函数, 清理托管资源和非托管资源的代码位置不要写反了,否则当一个托管对象已经被GC回收后,再去调用它的Dispose 方法, 系统会触发一个 ObjectDisposedException 异常到这里 ,一个简单的实现 IDisposable 的类已经写好了, 再写段测试代码看看
            private void button1_Click(object sender, EventArgs e)
            {
                classSample cls = new classSample();
            }
    点击按钮, 再关闭程序, 可看到 output 窗口中显示 对象被销毁 说明  Finalize 函数被执行了换一个
            private void button1_Click(object sender, EventArgs e)
            {
                classSample cls = new classSample();
                cls.Dispose();
            }再看 output 窗口中,只显示了”手动销毁对象“, 说明在手动执行Dispose 后,已正确通知GC,不再执行Finalize函数。小技巧: 可使用 using 关键字来定义对象的生存期,
    超出 using范围 后,如果对象实现了IDisposable接口, 系统会自动调用其 Dispose 方法, 是不是很方便。
                using (classSample cls = new classSample())
                {
                }
    看,我并没有调用 Dispose 方法, output 窗口中还会显示 ”手动销毁对象“. 此文引自:http://www.cnblogs.com/michaelhuwei/archive/2007/12/28/1018646.html
    本人认为比较好,建议楼主细体会,建议多给我分,
      

  11.   

    实现 Finalize 和 Dispose 以清理非托管资源类实例经常封装对不受运行库管理的资源(如窗口句柄 (HWND)、数据库连接等)的控制。因此,应该既提供显式方法也提供隐式方法来释放这些资源。通过在对象上实现受保护的 Finalize 方法(在 C# 和 C++ 中为析构函数语法)可提供隐式控制。当不再有任何有效的对象引用后,垃圾回收器在某个时间调用此方法。 在有些情况下,您可能想为使用该对象的程序员提供显式释放这些外部资源的能力,以便在垃圾回收器释放该对象之前释放这些资源。当外部资源稀少或者昂贵时,如果程序员在资源不再使用时显式释放它们,则可以获得更好的性能。若要提供显式控制,请实现由 IDisposable 接口提供的 Dispose 方法。在完成使用该对象的操作时,该对象的使用者应调用此方法。即使对对象的其他引用是活动的,也可以调用 Dispose。注意,即使在通过 Dispose 提供显式控制时,也应该使用 Finalize 方法提供隐式清理。Finalize 提供了候补手段,可防止在程序员未能调用 Dispose 时造成资源永久泄漏。有关如何实现 Finalize 和 Dispose 以清理非托管理资源的更多信息,请参见垃圾回收。下面的代码示例演示实现 Dispose 的基本设计方案。此示例需要 System 命名空间。
    public class Base: IDisposable
    {
      
       public void Dispose() 
       {
         Dispose(true);
          GC.SuppressFinalize(this); 
       }   protected virtual void Dispose(bool disposing) 
       {
          if (disposing) 
          {
             // Free other state (managed objects).
          }
       }   
       ~Base()
       {
                Dispose (false);
       }
    }
    public class Derived: Base
    {   
       protected override void Dispose(bool disposing) 
       {
          if (disposing) 
          {
             // Release managed resources.
          }      base.Dispose(disposing);
       }}
    有关阐释 Finalize 和 Dispose 的实现设计方案的更详细的代码示例,请参见实现 Dispose 方法。
    自定义释放方法名称有时特定于域的名称比 Dispose 更合适。例如,文件封装可能需要使用 Close 方法名称。在此情况下,可以通过专用方式实现 Dispose 并创建调用 Dispose 的公共 Close 方法。下面的代码示例阐释了这种模式。可以用适合您的域的方法名称替换 Close。此示例需要 System 命名空间。
    public void Close()
    {
       // Call the Dispose method with no parameters.
       Dispose();
    }
    Finalize下面的规则概括了 Finalize 方法的使用准则: 仅在要求终结的对象上实现 Finalize。存在与 Finalize 方法相关的性能开销。如果需要 Finalize 方法,应考虑实现 IDisposable,以使类的用户可以避免因调用 Finalize 方法而带来的开销。不要提高 Finalize 方法的可见性。该方法的可见性应该是 protected,而不是 public。对象的 Finalize 方法应该释放该对象拥有的所有外部资源。此外,Finalize 方法应该仅释放由该对象控制的资源。Finalize 方法不应该引用任何其他对象。不要对不是对象的基类的对象直接调用 Finalize 方法。在 C# 编程语言中,这不是有效的操作。应在对象的 Finalize 方法中调用基类的 Finalize 方法。 注意 
    基类的 Finalize 方法通过 C# 和 C++ 析构函数语法自动进行调用。
     
    释放
    下面的规则概括了 Dispose 方法的使用准则: 在封装明确需要释放的资源的类型上实现释放设计方案。用户可以通过调用公共 Dispose 方法释放外部资源。在通常包含控制资源的派生类型的基类型上实现释放设计方案,即使基类型并不需要也如此。如果基类型有 Close 方法,这通常指示需要实现 Dispose。在这类情况下,不要在基类型上实现 Finalize 方法。应该在任何引入需要清理的资源的派生类型中实现 Finalize。使用类型的 Dispose 方法释放该类型所拥有的所有可释放资源。对实例调用了 Dispose 后,应通过调用 GC.SuppressFinalize 方法禁止 Finalize 方法运行。此规则的一个例外是当必须用 Finalize 完成 Dispose 没有完成的工作的情况,但这种情况很少见。如果基类实现了 IDisposable,则应调用基类的 Dispose 方法。不要假定 Dispose 将被调用。如果 Dispose 未被调用,也应该使用 Finalize 方法释放类型所拥有的非托管资源。当资源已经释放时,在该类型上从实例方法(非 Dispose)引发一个 ObjectDisposedException。该规则不适用于 Dispose 方法,该方法应该可以在不引发异常的情况下被多次调用。 通过基类型的层次结构传播对 Dispose 的调用。Dispose 方法应释放由此对象以及此对象所拥有的任何对象所控制的所有资源。例如,可以创建一个类似 TextReader 的对象来控制 Stream 和 Encoding,两者均在用户不知道的情况下由 TextReader 创建。另外,Stream 和 Encoding 都可以获取外部资源。当对 TextReader 调用 Dispose 方法时,TextReader 应继而对 Stream 和 Encoding 调用 Dispose,使它们释放其外部资源。考虑在调用了某对象的 Dispose 方法后禁止对该对象的使用。重新创建已释放的对象是难以实现的方案。允许 Dispose 方法被调用多次而不引发异常。此方法在首次调用后应该什么也不做。部分版权所有 2005 Microsoft Corporation。保留所有权利。 部分版权所有 Addison-Wesley Corporation。保留所有权利。 有关设计指南的更多信息,请参见 Krzysztof Cwalina 和 Brad Abrams 编著、Addison-Wesley 于 2005 年出版的“Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries”(《框架设计指南:可重用 .NET 库的约定、术语和模式》)。 
      

  12.   

    实现 Dispose 方法 类型的 Dispose 方法应释放它拥有的所有资源。它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源。该父类型的 Dispose 方法应该释放它拥有的所有资源并同样也调用其父类型的 Dispose 方法,从而在整个基类型层次结构中传播此模式。若要确保始终正确地清理资源,Dispose 方法应该可以被多次调用而不引发任何异常。要点 
    C++ 程序员不应该使用本主题。而应参见 Destructors and Finalizers in Visual C++。在 .NET Framework 2.0 版中,C++ 编译器为实现资源的确定性处置提供支持,并且不允许直接实现 Dispose 方法。 
     Dispose 方法应该为它处置的对象调用 GC.SuppressFinalize 方法。如果对象当前在终止队列中,GC.SuppressFinalize 防止其 Finalize 方法被调用。请记住,执行 Finalize 方法会大大减损性能。如果您的 Dispose 方法已经完成了清理对象的工作,那么垃圾回收器就不必再调用对象的 Finalize 方法。注意 
    为 System.GC.KeepAlive(System.Object) 方法提供的代码示例演示了强行垃圾回收如何在回收对象的成员仍在执行时引起终结器运行。在较长的 Dispose 方法末尾最好调用 KeepAlive 方法。
     下面的代码示例旨在阐释用于为封装了非托管资源的类实现 Dispose 方法的建议设计模式。整个 .NET Framework 中都实现了此模式。 资源类通常是从复杂的本机类或 API 派生的,而且必须进行相应的自定义。使用这一代码模式作为创建资源类的一个起始点,并根据封装的资源提供必要的自定义。不能编译该示例,也不能将其直接用于应用程序。在此示例中,基类 BaseResource 实现可由该类的用户调用的公共 Dispose 方法。而该方法又调用 virtual Dispose(bool disposing) 方法(Visual Basic 中为 virtual Dispose(disposing As Boolean))。根据调用方的标识传递 true 或 false。以虚 Dispose 方法为对象执行适当的清理代码。Dispose(bool disposing) 以两种截然不同的方案执行。如果 disposing 等于 true,则该方法已由用户的代码直接调用或间接调用,并且可释放托管资源和非托管资源。如果 disposing 等于 false,则该方法已由运行库从终结器内部调用,并且只能释放非托管资源。因为终结器不会以任意特定的顺序执行,所以当对象正在执行其终止代码时,不应引用其他对象。如果正在执行的终结器引用了另一个已经终止的对象,则该正在执行的终结器将失败。基类提供的 Finalize 方法或析构函数在未能调用 Dispose 的情况下充当防护措施。Finalize 方法调用带有参数的 Dispose 方法,同时传递 false。不应在 Finalize 方法内重新创建 Dispose 清理代码。调用 Dispose(false) 可以优化代码的可读性和可维护性。类 MyResourceWrapper 阐释如何使用 Dispose 从实现资源管理的类派生。MyResourceWrapper 重写 virtual Dispose(bool disposing) 方法并为其创建的托管和非托管资源提供清理代码。MyResourceWrapper 还对其基类 BaseResource 调用 Dispose 以确保其基类能够适当地进行清理。请注意,派生类 MyResourceWrapper 没有不带参数的 Finalize 方法或 Dispose 方法,因为这两个方法从基类 BaseResource 继承这些参数。注意 
    此示例中的 protected Dispose(bool disposing) 方法不强制线程安全,因为无法从用户线程和终结器线程同时调用该方法。另外,使用 BaseResource 的客户端应用程序应从不允许多个用户线程同时调用 protected Dispose(bool disposing) 方法。应用程序或类库的设计原则为:应用程序或类库应只允许一个线程拥有资源的生存期,并且应在不再需要资源时调用 Dispose。根据资源的不同,在处置资源时进行异步线程访问可能会带来安全风险。开发人员应仔细检查自己的代码,以确定最佳的方法来强制线程安全。
     
    // Design pattern for the base class.
    // By implementing IDisposable, you are announcing that instances
    // of this type allocate scarce resources.
    public class BaseResource: IDisposable
    {
       // Pointer to an external unmanaged resource.
       private IntPtr handle;
       // Other managed resource this class uses.
       private Component Components;
       // Track whether Dispose has been called.
       private bool disposed = false;   // Constructor for the BaseResource object.
       public BaseResource()
       {
          // Insert appropriate constructor code here.
       }   // Implement IDisposable.
       // Do not make this method virtual.
       // A derived class should not be able to override this method.
       public void Dispose()
       {
          Dispose(true);
          // Take yourself off the Finalization queue 
          // to 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.
                Components.Dispose();
             }
             // Release unmanaged resources. If disposing is false, 
             // only the following code is executed.
             CloseHandle(handle);
             handle = IntPtr.Zero;
             // Note that this is not thread safe.
             // Another thread could start disposing the object
             // after the managed resources are disposed,
             // but before the disposed flag is set to true.
             // If thread safety is necessary, it must be
             // implemented by the client.      }
          disposed = true;         
       }   // 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.
       ~BaseResource()      
       {
          // Do not re-create Dispose clean-up code here.
          // Calling Dispose(false) is optimal in terms of
          // readability and maintainability.
          Dispose(false);
       }   // Allow your Dispose method to be called multiple times,
       // but throw an exception if the object has been disposed.
       // Whenever you do something with this class, 
       // check to see if it has been disposed.
       public void DoSomething()
       {
          if(this.disposed)
          {
             throw new ObjectDisposedException();
          }
       }
    }// Design pattern for a derived class.
    // Note that this derived class inherently implements the 
    // IDisposable interface because it is implemented in the base class.
    public class MyResourceWrapper: BaseResource
    {
       // A managed resource that you add in this derived class.
       private ManagedResource addedManaged;
       // A native unmanaged resource that you add in this derived class.
       private NativeResource addedNative;
       private bool disposed = false;  // Constructor for this object.
       public MyResourceWrapper()
       {
          // Insert appropriate constructor code here.
       }   protected override void Dispose(bool disposing)
       {
          if(!this.disposed)
          {
             try
             {
                if(disposing)
                {
                   // Release the managed resources you added in
                   // this derived class here.
                   addedManaged.Dispose();         
                }
                // Release the native unmanaged resources you added
                // in this derived class here.
                CloseHandle(addedNative);
                this.disposed = true;
             }
             finally
             {
                // Call Dispose on your base class.
                base.Dispose(disposing);
             }
          }
       }
    }// This derived class does not have a Finalize method
    // or a Dispose method without parameters because it inherits 
    // them from the base class.
      

  13.   

    实现 Close 方法
    对于类型来说,若调用 Close 方法比调用 Dispose 方法更容易,则可以向基类型添加一个公共 Close 方法。Close 方法又会调用没有参数的 Dispose 方法,该方法可以执行正确的清理操作。下面的代码示例阐释了 Close 方法。
    // Do not make this method virtual.
    // A derived class should not be allowed
    // to override this method.
    public void Close()
    {
       // Calls the Dispose method without parameters.
       Dispose();
    }
      

  14.   


    错了,是析构函数编译为Finalize函数的
      

  15.   

    最后...其实lz不必在意这些接口,方法,它就是一种设计模式。这么理解吧。你设计了一个类,类中要释放托管资源(如网络链接),
    那么你就要提供一个方法给程序员调用吧?好,方法名就叫 Dispose吧。好,问题来了,项目中好多类都封装了托管资源,也要释放,
    于是,我就让这些类都要实现一个接口,以释放托管资源,接口名就叫 IDispose吧。不爽的又来了,我有个文件操作的类,文件操作嘛,打开,关闭。用Dispose方法感觉怎么别扭呢?真不爽,于是我提供了一个Close方法,用来关闭文件,这样心里就爽了。其实也是调用Dispose方法。最后,现在的程序员素质真差,它就不调用Dispose或者Close,怎么办?不可能不释放这些资源吧?所以呢,我又实现了Finalize,在Finalize中最后释放托管资源,其实还是调用Dispose方法。最后大家都爽了。