接口IDisposable的用法

  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图形处理:betweeness中心性– neo4j的密码与graphstream

上周, 我写了关于中间性中心性算法以及使用graphstream 理解它的尝试 ,在阅读源代码时,我意识到我可以使用neo4j的所有最短路径算法将某些东西放在一起。 概括地说,中间性中心度算法用于确定图中节点的负载和重要性。 在与Jen讨…

java tongpaiyu danliantiao_java版的汉字转拼音程序

[文件] ChiToLetter.javaimport java.io.UnsupportedEncodingException;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import java.util.Vector;//实现汉字向拼音的转化//-----------------------------------------------------设计人:牛文平// …

小程序之Tab切换

小程序越来越火了,作为一名,额 有理想的攻城狮,当然要紧跟互联网时代的步伐啦,于是我赶紧抽时间学习了一下小程序的开发,顺便把经验分享给大家。 对于申请账号以及安装开发工具等,大家可以看官网&#xff…

configparser logging

configparser模块 # 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键值)。 import configparser config configparser.ConfigParser() c…

JS结合Cookie实现验证码功能

验证码功能是现在网站开发中非常常见的一种功能,常见的编程语言,比如.NET,JAVA都能很容易实现验证码功能,今天我准备分享一个使用JS实现验证码的功能,非常简单使用,拿来就可以用,废话不多说,直接…

创建基于密码的加密密钥

本文讨论了创建基于密码的加密PBE密钥。 首先提醒您以前的要点–通常,在实际操作中,应将PBE密钥用作主密钥,该主密钥仅用于解锁工作密钥。 这具有三个主要优点: 您可以有多个密码,例如,托管的恢复密钥&am…

php-5.6.26源代码 - PHP文件汇编成opcode、执行

文件 php-5.6.26/Zend/zend.c ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */ {va_list files;int i;zend_file_handle *file_handle;zend_op_array *orig_op_array EG(active_op_array); // 保存现场,操作…

java1a2b3c4d5e6f_用两个线程,一个输出字母,一个输出数字,交替输出1A2B3C4D...26Z...

用两个线程,一个输出字母,一个输出数字,交替输出1A2B3C4D...26Z方法一public class Test {static Thread t1 null, t2 null;public static void main(String[] args) {char[] aI "1234567".toCharArray();char[] aC "ABCD…

js如何设置浏览器全屏效果?

现在很多网页游戏进入游戏界面后都是全屏显示的效果,很多人问我这个要怎么实现,其实这个只要调用Fullscreen API就可以实现了作为一个比较新的 API,目前只有 Safari、Chrome 和 FireFox以及IE10以上的浏览器才支持该特性。因为尚未发布正式版…

6759: 异或序列

6759: 异或序列 时间限制: 1 Sec 内存限制: 128 MB题目描述 已知一个长度为n的整数数列a1,a2,…,an,给定查询参数l、r,问在al,al1,…,ar区间内,有多少子序列满足异或和等于k。也就是说,对于所有的x,y(l≤x≤y≤r),满足…

Neo4j Java REST绑定–第2部分(批处理)

在第1部分中 ,我们讨论了使用Java REST绑定建立与Neo4j Server的连接。 现在让我们详细了解事务,批处理以及REST请求的实际情况。确保org.neo4j.rest.logging_filter to true) as described in Part 1打开日志记录(将系统属性org.neo4j.rest.…

selector简介

最近在学习java NIO,发现java nio selector 相对 channel ,buffer 这两个概念是比较难理解的 ,把学习理解的东西以文字的东西记录下来,就像从内存落地到硬盘,把内存中内容换成该知识点的索引。 在介绍Selector之前先明确以下3个问题&#…

java随机数排序算法_理解快速排序算法

快速排序在平均状况下,排序n个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n^2)次比较,但这种状况并不常见。事实上,快速排序通常明显比 其他Ο(n log n)算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地…

开课吧视频内容汇总

1. 前端读取文件内容, FileReader对象 2. 用户联网状态 3. application/x-www-form-urlencoded 参数序列化 (具体借鉴jquery的$.param方法),后端接收到的数据格式是 a[0][a] 1,并不会将其整理成对象或者数组 var nextStr ;funct…

PhantomJS宣布终止开发

由于没有人贡献代码,我很快就要把这个项目归档了。也许未来的某一天,我又想开发了,还会重新启动起来。既然决定停止开发了,那么自然地,PhantomJS 2.5 和原定的 PhantomJS2.1.x 就告吹了。对应的,这两个版本…

Servlet和JSP中的文件上传示例

使用Servlet和JSP将文件上传到服务器是Java Web应用程序中的常见任务。 在对Servlet或JSP进行编码以处理文件上传请求之前&#xff0c;您需要了解一点有关HTML和HTTP协议中文件上传支持的知识。 如果要让用户从文件系统中选择文件并上传到服务器&#xff0c;则需要使用<inpu…

20165312-第4周-课上内容补做以及知识点总结

20165312-第4周-课上内容补做以及知识点总结 1、课上内容补做 教材代码完成情况测试p45这题很快就做完了&#xff0c;然后忘记提交了。。就开始做递归。想起来的时候已经过了时间。 public class Example3_7 {public static void main(String args[]) {int sum0,i,j;for(i1;i&l…

java入门就是死敲代码吗_JAVA入门第二季综合练习(直接思考敲的代码,面向过程,不好)...

package com.imocc;/*author ndh2016年3月27日 21:03:02*/import java.util.Scanner;public class DiDi {public static void main(String[] args){Scanner sc new Scanner(System.in);System.out.println("欢迎使用迪迪租车系统&#xff01;");System.out.println(…

JavaScript实现表单的全选,反选,获取值

构思 通过for循环和for in循环来实现&#xff0c;界面效果如下 步骤 全选&#xff1a; 循环给所有的表单设置checked 反选&#xff1a; 循环内判断checked是否为true&#xff0c;如果为true则改为false否则改为true 获取值&#xff1a; 最开始用for取&#xff0c;但是只打印最后…

jQuery.extend() 使用语法详解

今天在写插件&#xff0c;使用$.extend({}, defaults, options)的时候发现漏写了 {}&#xff0c;浪费了一些时间&#xff0c; 所以详细记录下该方法的 API 和使用。API 如下&#xff1a;jQuery.extend( [ deep ], target, [ object1 ], [ objectN ] )描述&#xff1a;合并两个或…