C#的每一个类型都代表一种资源,而资源又分为两类:

  • 托管资源  由CLR管理分配和释放的资源,即从CLR里new出来的对象。
  • 非托管资源  不受CLR管理的对象,如Windows内核对象,或者文件、数据库连接、套接字、COM对象等。

  如果类型用到了非托管资源,或者需要显式释放托管资源,那么需要让类型继承接口IDisposable。记住:如果类型需要显式释放资源,那么一定要继承IDisposable接口。如:

class SampleClass:IDisposable
{private IntPtr nativeResource = Marshal.AllocHGlobal(100);//非托管资源private Bitmap bitmap = new Bitmap(100, 100);//托管资源private bool isDisposed = false;//实现IDisposable中的Dispose方法public void Dispose( ){Dispose(true);GC.SuppressFinalize(this);//通知垃圾回收器不用再调用终结器
    }//不必要的方法,只是为了符合其他语言的规范public void Close(){Dispose();}//必须的,防止程序员忘记显示调用Dispose方法(隐式清理)~SampleClass(){Dispose(false);}//非密封类修饰用protected virtual,提醒子类必须实现自己的清理方法时注意到父类的清理工作protected virtual void Dispose(bool isDisposing){if(isDisposed){return;}if(isDisposing){//清理托管资源if(bitmap != null){bitmap.Dispose();bitmap = null;}}//清理非托管资源if(nativeResource!=IntPtr.Zero){Marshal.FreeHGlobal(nativeResource);nativeResource = IntPtr.Zero;}isDisposed = false;}public void SamplePublicMethod(){if(isDisposed){throw new ObjectDisposedException("SampleClass", "SampleClass is disposed");}//代码
    }
}

View Code

  继承IDisposable接口,可以使用using语法糖。在using语句代码块内,可以使用声明的对象,当语句离开代码块后,系统自动释放资源:

//使用using方法,当语句离开代码块后,using内的对象自动释放
using (SampleClass sample = new SampleClass())
{//……
}
//以上代码相当于下面的代码
SampleClass sample0 = new SampleClass();
try
{//……
}
finally
{sample0.Dispose();
}

View Code

  在SampleClass中,存在一个终结器(C++中叫析构器)。其意义在于,调用者可能并不会主动调用Dispose方法,而终结器会被垃圾回收器调用调用,所以它作为释放资源的补救措施。

  在CLR中,每new一个对象时,就会为该对象在堆上分配内存,如果不再被引用,就会回收它们的内存。如果没有实现IDisposable接口的类型对象,垃圾回收器会直接释放对象所占内存;如果实现了,每次创建对象时,CLR会将该对象的一个指针放到终结列表中,垃圾回收器在回收对象前会首先将终结列表中的指针放入一个freachable队列。同时,CLR会分配一个线程管理freachable队列,调用对象终结器,只有此时,对象才会被真正标识为垃圾,并在下一次进行垃圾回收时释放对象所占内存。即:实现IDisposable接口的类型,至少要经过两次垃圾回收才能真正释放掉内存。其中Dispose方法中的GC.SuppressFinalize()方法用于在显示释放资源后,通知垃圾回收器不用再调用终结器(隐式回收)释放资源。

  在实现IDisposable接口时,其Dispose()方法并没有做实际的清理工作,但提供了带bool参数的受保护的虚方法。因为该类型可能被其他类继承,如果子类实现自己的Dispose模式,受保护的虚方法可以提醒子类:在实现自己的清理方法时,需要注意父类的清理工作(base.Dispose方法)。

  真正撰写资源释放代码的虚方法有一个bool参数,但是在显示释放资源(true)与隐式释放资源(false)调用中传入的参数不同。表明:隐式清理时,只需要处理非托管资源就行。托管资源中的普通类型不需要手动清理,而非普通类型需要手动清理。

  Dispose模式设计思路:如果调用者显示调用了Dispose方法,那么类型按部就班释放自己的全部资源,然后通知垃圾回收器不需要再释放(GC.SuppressFinalize()方法);而忘记调用Dispose方法,那么类型就假定自己的所有托管资源会全部交给垃圾回收器回收,不需要手动清理。

转载于:https://www.cnblogs.com/pilgrim/p/9276930.html

接口IDisposable的用法相关推荐

  1. swagger自动创建接口文档用法

    现在的开发大部分都是前后端分离的模式了,后端提供接口,前端调用接口.后端提供了接口,需要对接口进行测试,之前都是使用浏览器开发者工具,或者写单元测试,再或者直接使用Postman,但是现在这些都已经o ...

  2. Java接口回调一般用法

    实现接口实际上和继承抽象类类似,只不过继承是在类的层面上操作,接口是在方法和常量集合的层面上操作,接口比抽象类更抽象.更简洁.可以把实现接口看成继承特定的一个或多个方法以及一些常量,关于接口的具体规则 ...

  3. php 接口的定义与实现,PHP接口定义与用法示例

    使用接口(interface),你可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容.我们可以通过interface来定义一个接口,就像定义一个标准的类一样,但其中定义所有的方法都是空的. ...

  4. 链接太长如何缩短?稳定的短链接api接口分享与用法实例

    网络营销中的微信,短信,微博和软文推广中链接太长非常影响营销效果,那么如何将长链接缩短成短链接呢?今天给大家讲解下网址缩短方式,以新浪短网址http://t.cn/xxx和腾讯短网址http://ur ...

  5. 函数式接口Supplier的用法

    文章目录 前言 supplier接口定义 具体使用 前言 最近看到公司写的rpc框架中,运用到了大量的函数式接口Supplier,下面将对supplier接口的具体使用简单介绍. supplier接口 ...

  6. 大数据 -- java基础8 接口特点和用法

    1.接口:interface关键字     (1)语句定义格式: interface 接口名{} (2)接口是如何实现的呢?         接口不能直接实例化,需要一个关键字供其他类实现该接口:im ...

  7. vue学习笔记-接口调用fetch用法

    一,fetch概述 二,fetch基本用法 第一个then是fetch的一部分,返回一个promise对象,于是可以继续用then来处理返回的结果ret. 这段代码是服务器的代码: //这是在创建服务 ...

  8. [转载]快递接口的典型用法

    转载自:http://hi.baidu.com/near360/blog/item/b28c81190a3fbc1b35fa41be.html?timeStamp=1319095737792 客户老是 ...

  9. 自动化测试——接口自动化——requests用法

    import requests #1.get请求,查询所有学院信息 #请求地址 url01="http://127.0.0.1:8000/api/departments/" #设置 ...

最新文章

  1. Attention的相关工作
  2. 无意中发现了一位清华大佬的代码模版
  3. PAT:1019. 数字黑洞 (20) AC(同甲级1069)
  4. 图像去畸变和添加畸变
  5. 因为没钱买衣服,我女朋友不要我了......
  6. 如何给女朋友解释什么是3PC?
  7. mysql begin operations_MySQL入门(七):More JOIN operations
  8. git pull rebase
  9. (18)Zynq FPGA 看门狗定时器介绍
  10. Quartz配置RMI设置-006
  11. R7900P/R7960P/R8000P梅林固件
  12. 路飞学城python全栈开发_[Python] 老男孩路飞学城Python全栈开发重点班 骑士计划最新100G...
  13. Acess错误:文件共享锁定数溢出
  14. 游戏编辑器制作(6)
  15. 让吹牛都能全世界最棒
  16. 在Silverlight 2 beta1中使用IronPython等动态语言
  17. 适用于Windows11 任务栏开始菜单和图标,资源管理器显示异常修复的方法
  18. 【板栗糖GIS】如何免费下载landsat8的遥感影像数据
  19. GooglePlay区分推荐来源
  20. CentOS 安装 微软雅黑字体

热门文章

  1. 极光推送服务端API(定时推送任务,推送到指定设备,推送到所有设备)
  2. confluence 为合并的单元格新增一行
  3. 【黑金原创教程】【TimeQuest】【第二章】TimeQuest模型角色,网表概念,时序报告...
  4. Linux常用命令和vi,gdb的使用
  5. CSS伪类的三种写法
  6. 8. Action过滤
  7. 正则查找倒数第二个符合条件的字符串_EXCEL正则表达式的基础语法
  8. StarUML使用说明-指导手册
  9. HDU题目分类啊!!!
  10. python settings模块导入不了_无法导入设置“myproject.settings”(是否在sys.path上?):没有名为pinax的模块...