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 void DoSomething() 
...{
Console.WriteLine("Do some thing....");
}
public void Dispose() 
...{
Console.WriteLine("及时释放资源");
}
} 
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使用实例
...{
//是否回收完毕
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;
}
}
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的原因是希望有子类可以一起参与到垃圾回收逻辑的设计,而且还不会影响到基类。
比如有这样的一个子类
...{
private bool _disposed; //表示是否已经被回收
protected override void Dispose(bool disposing) 
...{
if(!_disposed) //如果还没有被回收 
...{
if(disposiing) //如果需要回收一些托管资源 
...{
//TODO:回收托管资源,调用IDisposable的Dispose()方法就可以
}
//TODO:回收非托管资源,把之设置为null,等待CLR调用析构函数的时候回收
_disposed = true;
}
base.Dispose(disposing);//再调用父类的垃圾回收逻辑
}
} 
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的更多相关文章
- C#中IDisposable学习
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- .NET中IDisposable接口的基本使用
首先来看MSDN中关于这个接口的说明: [ComVisible(true)] public interface IDisposable { // Methods void Dispose(); } 1 ...
- C#中IDisposable的用法
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- C#中IDisposable的用法-垃圾回收
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- IDisposable接口
C#中IDisposable接口的主要用途是释放非托管资源.当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存.但无法预测进行垃圾回收的时间.另外,垃圾回收器对窗口句柄或打开的文件和流等非托 ...
- TFS二次开发、C#知识点、SQL知识总结目录
TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一个实例 TFS二次开发系列:四.TFS二次开发Wor ...
- TFS二次开发、C#知识点、SQL知识
TFS二次开发.C#知识点.SQL知识总结目录 TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一 ...
- Core官方DI解析(2)-ServiceProvider
ServiceProvider ServiceProvider是我们用来获取服务实例对象的类型,它也是一个特别简单的类型,因为这个类型本身并没有做什么,其实以一种代理模式,其核心功能全部都在IServ ...
- Python开源框架
info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...
随机推荐
- learn from 德国老师
最近在跟踪德国来的一个老师学android,感触比较深的一点就是他对细节的理解,一个源代码他可以从第一行解释到最后一行,知道每一行的意思和用法,这可能就是德国人对细节的追求. 刚才想了一下写代码确实应 ...
- SIFT
简介 SIFT(scale invariant feature transform)——尺度不变特征转换,用来检测和描述局部特征,运用范围包括object recognition(目标检测), rob ...
- http://mozilla.debian.net/
deb http://mozilla.debian.net/ wheezy-backports iceweasel-release You can install it with the follow ...
- 深度学习框架Caffe的编译安装
深度学习框架caffe特点,富有表达性.快速.模块化.下面介绍caffe如何在Ubuntu上编译安装. 1. 前提条件 安装依赖的软件包: CUDA 用来使用GPU模式计算. 建议使用 7.0 以上最 ...
- javascript深入理解js闭包(看了挺多的,感觉这篇比较透彻)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- SQL Server--导入和导出向导
作用:创建一个只需要最少的转换就可以快速导入或导出数据的包 操作步骤: 1 打开打入和导出向导方式 有四种方式 1)在SSMS(SQL Server Management Studio)中,右击目标数 ...
- nginx 生成 缩略图 and 生成缩略图到硬盘
nginx 编译的时候增加 ./configure --with-http_image_filter_module 配置如下 server { listen 80; server_name ...
- CSDN泄漏数据完整分析
CSDN泄漏数据完整分析 2011-12-22 08:59:26 53391 次阅读 0 条评论 感谢mayee的投递 昨天CSDN的用户数据库被人在网上公布.我下载分析了下里面的数据,得出了一些很有 ...
- bootstrap switch功能
bootstrap switch是一个按钮开关,点击时获取其状态可通过以下代码: <input id="email_switch_state" type="chec ...
- POJ 2373 Yogurt factory
简单DP. 这周所用的实际花费是上一周的花费+S与这周费用的较小值. #include<cstdio> #include<cstring> #include<cmath& ...