C#中IDisposable学习
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机。对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收。那么什么时候使用Idisposable接口,以及如何使用呢?
一、IDisposable的接口定义如下
public interface IDisposable
{
// Summary:
// Performs application-defined tasks associated with freeing, releasing, or
// resetting unmanaged resources.
void Dispose();
}
二:IDisposable基本应用
1.定义一个实现了IDisposable接口的类
public class CaryClass :IDisposable
{
public void DoSomething()
{
Console.WriteLine("Do some thing....");
}
public void Dispose()
{
Console.WriteLine("及时释放资源");
}
}
2、两种方式来调用
(1)、使用Using语句会自动调用Dispose方法
using (CaryClass caryClass = new CaryClass())
{
caryClass.DoSomething();
}
(2)、现实调用该接口的Dispose方法
CaryClass caryClass = new CaryClass();
try
{
caryClass.DoSomething();
}
finally
{
IDisposable disposable = caryClass as IDisposable;
if (disposable != null)
disposable.Dispose();
}
三、IDisposable使用实例
public class DisposablClass : IDisposable
{
//是否回收完毕
bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableClass()
{
Dispose(false);
}
//这里的参数表示示是否需要释放那些实现IDisposable接口的托管对象
protected virtual void Dispose(bool disposing)
{
if(_disposed) return; //如果已经被回收,就中断执行
if(disposing)
{
//TODO:释放那些实现IDisposable接口的托管对象
}
//TODO:释放非托管资源,设置对象为null
_disposed = true;
}
}
四、IDisposable实例分析
Dispose()方法
当需要回收非托管资源的DisposableClass类,就调用Dispoase()方法。而这个方法不会被CLR自动调用,需要手动调用。
~DisposableClass(),析构函数
当托管堆上的对象没有被其它对象引用,GC会在回收对象之前,调用对象的析构函数。这里的~DisposableClass()析构函数的意义在于告诉GC你可以回收我,Dispose(false)表示在GC回收的时候,就不需要手动回收了。
虚方法Dispose(bool disposing)
1、通过此方法,所有的托管和非托管资源都能被回收。参数disposing表示是否需要释放那些实现IDisposable接口的托管对象。
2、如果disposings设置为true,就表示DisposablClass类依赖某些实现了IDisposable接口的托管对象,可以通过这里的Dispose(bool disposing)方法调用这些托管对象的Dispose()方法进行回收。
3、如果disposings设置为false,就表示DisposableClass类依赖某些没有实现IDisposable的非托管资源,那就把这些非托管资源对象设置为null,等待GC调用DisposableClass类的析构函数,把这些非托管资源进行回收。
4、另外,以上把Dispose(bool disposing)方法设置为protected virtual的原因是希望有子类可以一起参与到垃圾回收逻辑的设计,而且还不会影响到基类。
比如有这样的一个子类
public class SubDisposableClass : DiposableClass
{
private bool _disposed; //表示是否已经被回收
protected override void Dispose(bool disposing)
{
if(!_disposed) //如果还没有被回收
{
if(disposiing) //如果需要回收一些托管资源
{
//TODO:回收托管资源,调用IDisposable的Dispose()方法就可以
}
//TODO:回收非托管资源,把之设置为null,等待CLR调用析构函数的时候回收
_disposed = true;
}
base.Dispose(disposing);//再调用父类的垃圾回收逻辑
}
}
五、IDisposable总结
当我们自定义的类及其业务逻辑中引用某些托管和非托管资源,就需要实现IDisposable接口,实现对这些资源对象的垃圾回收。
C#中IDisposable学习的更多相关文章
- 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)
今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...
- PHP实例开发(3)PHP中MVC学习之ThinkPHP
PHP中MVC学习之ThinkPHP 1.什么是MVC MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器.使用MVC的目的是将M和V的实现代码分离 MVC是一个设 ...
- 转:openwrt中luci学习笔记
原文地址:openwrt中luci学习笔记 最近在学习OpenWrt,需要在OpenWrt的WEB界面增加内容,本文将讲述修改OpenWrt的过程和其中遇到的问题. 一.WEB界面开发 ...
- VS2013中Python学习笔记[Django Web的第一个网页]
前言 前面我简单介绍了Python的Hello World.看到有人问我搞搞Python的Web,一时兴起,就来试试看. 第一篇 VS2013中Python学习笔记[环境搭建] 简单介绍Python环 ...
- VS2013中Python学习环境搭建
VS2013中Python学习笔记[环境搭建] 前言 Python是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python的设计具有很强的可读性,相比其他语言经常使用英文关键字, ...
- 在NLP中深度学习模型何时需要树形结构?
在NLP中深度学习模型何时需要树形结构? 前段时间阅读了Jiwei Li等人[1]在EMNLP2015上发表的论文<When Are Tree Structures Necessary for ...
- PHP中正则表达式学习及应用(四)
正则表达式在PHP中的应用 1.匹配功能 2.替换功能 3.分割功能 例如: <?php $str="addsds{title}hfksjd{author}hfjdkjd{conn}j ...
- PHP中正则表达式学习及应用(三)
正则表达式中的“模式修正符” 1.运算顺序 2.模式修正符 i 正则内容在匹配时候不区分大小写(默认是区分的) 例如: <?php $mode="/[a-z]/i"; ...
- PHP中正则表达式学习及应用(二)
正则表达式中的“元字符” * 匹配前一个内容的0次1次或多次 例如: <?php $mode="/go*gle/"; //前一个内容指的是 * 的前一个字符 o ,在$str ...
随机推荐
- 通过google找网站后台的方法
转自:http://cyuyanbiancheng.blog.hexun.com/69239903_d.html site:url.com '查看这个站点上的信息最好不加www,可以查看到不少的二级域 ...
- Java获取线程的对象和名称
/*获取线程对象以及名称(很有意义的) 原来线程都有自己默认的名称Thread-编号 该编号从0开始 Thread 父类的方法static Thread currentThread() :获取当前 ...
- java_集合框架
一.集合框架图 二.Collection接口 Collection中可以存储的元素间无序,可以重复的元素. Collection接口的子接口List和Set,Map不是Collecti ...
- [leetcode] 398. Random Pick Index
我是链接 看到这道题,想到做的几道什么洗牌的题,感觉自己不是很熟,但也就是rand()函数的调用,刚开始用map<int, vector<int >>来做,tle,后来就想着直 ...
- mysql show processlist 显示mysql查询进程
1.进入mysql/bin目录下输入mysqladmin processlist; 2.启动mysql,输入show processlist; 如果有 SUPER 权限,则可以看到全部的线程,否则,只 ...
- Linux – RedHat7 / CentOS 7 忘记root密码修改
1.(a) 开机出现grub boot loader 开机选项菜单时,立即点击键盘任意鍵,boot loader 会暂停. (b) 按下’e’,编辑选项菜单(c) 移动上下鍵至linux16 核心命令 ...
- socket 基础学习
这个示例程序是同步套接字程序,功能很简单,只是客户端发给服务器一条信息,服务器向客户端返回一条信息:这里只是一个简单的示例,是一个最基本的socket编程流程,在接下来的文章中,会依次记录套接字的同步 ...
- input效果:当鼠标在input中输入文字是改变内部文字效果
主要用到属性:onpropertychange事件(属性改变时触发的事件),oninput属性(当input有输入时发生的事件) onpropertychange事件是IE专属事件 oninput属性 ...
- div+css实现的左右两个等高div
工作当中我们经常会有这样的需求,尤其是在一些内容页面或者网站后台管理页面:左边的div的高度会随着右边的div的内容的增加儿增加,右边div的高度也会随着左边div的内容的增加而增加,也就是左右两侧两 ...
- lamp环境centos5.10,phpprotobuf模块安装,及简单应用
==相关参考== rpm包 http://rpmfind.net/linux/rpm2html/ Linux rpm 命令参数使用详解[介绍和应用] phpize学习 http://blog.sina ...

{
public void DoSomething()
{
}
}