zoukankan      html  css  js  c++  java
  • C#中标准Dispose模式的实现与使用(条目17 实现标准的销毁模式)

    实现了Dispose模式与实现了IDisposable接口的区别就是:IDisposable的实现的可靠性(释放相关资源)要靠编程人员来解决(你确信你从来都一直调用了Dispose(Close)方法吗?),而实现了Dispose模式后,当编程人员没有主动调用Dispose方法时,会由终结器来调用(有些时候编程人员想主动调用也调用不了,比如远程连上来的TcpChannel,客户端断开时,服务端只能由终者器调用)。

    Dispose模式()的实现需要以下4个步骤:
    1. 释放所有非托管资源;
    2. 释放所有托管资源,包括释放事件监听程序;
    3. 设计一个状态标志(IsDisposed),表示该对像已经被销毁。若是在销毁后再次调用对像的公有方法,那么应该抛出ObjectDisposed异常;
    4. 跳过终者操作,调用CG.SuppressFinalize(this)即可。

    注:
    ------------------
    托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象;
    非托管资源:不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等;

    用实现来说明。
    EXAMPLE CODE:

    using System;
    
    namespace CS.DesignPatterns
    {
        /// <summary>
        /// 示例
        /// </summary>
        public class DisposePatternSample:IDisposable
        {
            private bool _isDisposed;//是否已释放了资源,true时方法都不可用了。
    
            public DisposePatternSample()
            {
                _isDisposed = false;
            }
    
            public void MethodSample()
            {
                if(_isDisposed)
                    throw new ObjectDisposedException("inner resource is disposed.");
                Console.WriteLine("MethodSample is called.");
            }
    
            /// <summary>
            /// 为继承类释放时使用
            /// <remarks>
            /// Note:这儿为什么要写成虚方法呢?
            /// 1. 为了让派生类清理自已的资源。将销毁和析构的共同工作提取出来,并让派生类也可以释放其自已分配的资源。
            /// 2. 为派生类提供了根据Dispose()或终结器的需要进行资源清理的必要入口。
            /// </remarks>
            /// </summary>
            /// <param name="isDisposing"></param>
            protected virtual void Dispose(bool isDisposing)
            {
                if(_isDisposed)return;
                
                if (isDisposing)
                {
                    //释放托管资源
                    //(由CLR管理分配和释放的资源,即由CLR里new出来的对象)
                    //TODO: other code
                }
    
                //释放非托管资源
                //(不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等)
                //TODO: other code
    
                _isDisposed = true;
            }
    
            #region IDisposable 成员
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            #endregion
    
            ///// <summary>
            ///// 如果没有非托管资源,不要实现它
            ///// </summary>
            //~DisposePatternSample()
            //{
            //    Dispose(false);
            //}
        }
    
    
        public class DrivedDisposePatternSample : DisposePatternSample
        {
            private bool _isDisposed = false; //各类维护自已的释放状态,把可能出现的错误限制在类本身
    
            /// <summary>
            /// 子类清理自已的资源时使用
            /// </summary>
            /// <param name="isDisposing"></param>
            protected override void Dispose(bool isDisposing)
            {
                if(_isDisposed)return;
                if (isDisposing)
                {
                    //释放托管资源
                    //(由CLR管理分配和释放的资源,即由CLR里new出来的对象)
                    //TODO: other code
                }
    
                //释放非托管资源
                //(不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等)
                //TODO: other code
    
                //基类释放资源
                //基类负责调用GC.SuppressFinalize()
                base.Dispose(isDisposing);
    
                _isDisposed = true;
            }
    
            ///// <summary>
            ///// 如果没有非托管资源,不要实现它
            ///// </summary>
            //~DrivedDisposePatternSample()
            //{
            //    Dispose(false);
            //}
    
        }
    
    }

     

    上述的代码并没有使用析构方法,这是因为上述的代码并没有使有非托管资源(永远不会调用Dispose(false))方法。注意:除非你调用了非托管资源,否则不要实现析构方法。即使析构器永远不会被调用,它本身也会极大的影响类型的性能。不要画蛇添足。不过这个模式却不能改变,因为你的派生类可能会用到非托管的资源。

    重要的建议:只能在Dispose方法中释放资源,不得进行其它操作(如果一不小心的其它操作,让本该死亡的对象起死回生,哼哼~~~~)。

    请遵守Dispose标准模式的实现,这会节省你,你的类型使用者,你的类型的派生者的大量的时间。

  • 相关阅读:
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Python位运算符
  • 原文地址:https://www.cnblogs.com/atwind/p/3447296.html
Copyright © 2011-2022 走看看