IDisposable概述

GC(垃圾收集器)只能回收托管(Managed)内存资源,对于数据库连接、文件句柄、Socket连接等这些资源(非托管资源,UnManaged)就无能为例,必须程序员自己控制资源的回收。非托管资源:SqlConnection、FileStream等。

  对于使用非内存资源的类,完全可以自己定义一个销毁资源的方法来供程序员回收,.net推荐实现IDisposable接口(为了规范非托管资源的回收),在Dispose方法中进行回收。

  实现了IDisposable接口的对象都可以使用using进行资源管理。using就是帮我们做了:

FileStream fs = new F.....
try {  
fs.read()....
}
finally {
fs.Dispose();
}

  实现了IDisposable接口的对象都要进行回收,否则很可能有内存泄露。

  非托管内存资源才需要实现IDisposable

IDisposable例子

namespace 资源回收
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用using对实现IDisposable的类了进行资源管理
/*拿到一个对象的时候,首先判断这个对象是否实现了IDisposable接口,如果实现了,最好就用using包裹住这个对象,保证这个对象用完之后被释放掉,否则很可能出现资源泄露的问题
*/
            using (Telphone t1 = new Telphone())
            {
                t1.Open();
                t1.Speak("hello");
                t1.Bomb();
                //t1.Dispose();//如果在这里调用了Dispose()方法释放资源,那么在执行t1.Open()方法就出错,电话线已经被剪断了,无法再打电话了
                t1.Open();
                t1.Speak("I am back!");
            }//代码执行到这里后,就会调用Dispose方法来进行资源回收
            Console.ReadKey();
        }
    }
    /// <summary>
    /// Telphone类实现了IDisposable接口
    /// </summary>
    class Telphone : IDisposable
    {
        /// <summary>
        /// 电话状态
        /// </summary>
        private TelphoneState state;
        /// <summary>
        /// 打电话
        /// </summary>
        public void Open()
        {
            if (state == TelphoneState.Disposed)
            {
                throw new Exception("电话线已经被剪断,无法打开!");
            }
            state = TelphoneState.Open;
            Console.WriteLine("拿起电话");
        }
        /// <summary>
        /// 说话
        /// </summary>
        /// <param name="s">说话内容</param>
        public void Speak(string s)
        {
            if (state != TelphoneState.Open)
            {
                throw new Exception("没有连接");
            }
            Console.WriteLine(s);
        }
        /// <summary>
        /// 挂掉电话
        /// </summary>
        public void Bomb()
        {
            state = TelphoneState.Close;
            Console.WriteLine("挂掉电话");
        }
        #region IDisposable 成员
        /// <summary>
        /// 实现IDisposable接口中的Dispose()方法来释放非托管资源
        /// 如何释放非托管资源由程序自己定
        /// </summary>
        public void Dispose()
        {
            if (state == TelphoneState.Open)
            {
                Bomb();//挂掉电话
            }
            state = TelphoneState.Disposed;
            Console.WriteLine("剪断电话线");
        }
        #endregion
    }
    /// <summary>
    /// 电话状态枚举
    /// </summary>
    enum TelphoneState
    {
        Open, Close, Disposed
    }
}

程序运行结果:
这里写图片描述

  Dispose中通常会顺便调用Close,这只是实现类自己的行为,没人强求, IDisposable中的 Dispose方法根本不知道Close方法的存在,甚至可以没有close方法。(Close与Dispose关系 常考)。没有规定Dispose一定会调用Close方法,但是很多的实现了IDisposable接口的方法中,通常都是代为调用Close之类的方法。一般的close只是关闭,也许关闭后还能打开,但是Dispose一般就表示资源被回收了,再也没法用了。有的类可能没有close方法。

Close和Dispose的区别:

1、一个类如果实现IDisposable接口,则肯定有Dispose这个方法。但是一个类可以没有Close方法,也可以不叫Close。

2、即使像SqlConnection、FileStream这种有Close也有Dispose方法的,IDisposable接口也没有约定Dispose必须帮助Close,只不过一般的Dispose的实现都判断是否Close,如果没有Close则帮助Close,但是这是好心、不是义务。

原文请点击此处

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值