IDisposable接口
C#中IDisposable接口的主要用途是释放非托管资源。当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。但无法预测进行垃圾回收的时间。另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。将此接口的Dispose方法与垃圾回收器一起使用来显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。
在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接口,实现对这些资源对象的垃圾回收。
IDisposable接口的更多相关文章
- C#中对IDisposable接口的理解
http://blog.sina.com.cn/s/blog_8abeac5b01019u19.html C#中对IDisposable接口的理解 本人最近接触一个项目,在这个项目里面看到很多类实现了 ...
- IDisposable 接口2
定义一种释放分配的资源的方法. 命名空间: System程序集: mscorlib(在 mscorlib.dll 中) 语法 C# C++ F# VB [ComVisibleAttribute(t ...
- IDisposable接口详解
转载:http://www.cnblogs.com/davyli/archive/2010/09/13/1825042.html 正确实现 IDisposable .NET中用于释放对象资源的接口是I ...
- .NET中IDisposable接口的基本使用
首先来看MSDN中关于这个接口的说明: [ComVisible(true)] public interface IDisposable { // Methods void Dispose(); } 1 ...
- 利用IDisposable接口构建包含非托管资源对象
托管资源与非托管资源 在.net中,对象使用的资源分为两种:托管资源与非托管资源.托管资源由CLR进行管理,不需要开发人员去人工进行控制,.NET中托管资源主要指"对象在堆中的内存" ...
- 深入理解C#中的IDisposable接口
写在前面 在开始之前,我们需要明确什么是C#(或者说.NET)中的资源,打码的时候我们经常说释放资源,那么到底什么是资源,简单来讲,C#中的每一种类型都是一种资源,而资源又分为托管资源和非托管资源,那 ...
- C#中的IDisposable接口
深入理解C#中的IDisposable接口 写在前面 在开始之前,我们需要明确什么是C#(或者说.NET)中的资源,打码的时候我们经常说释放资源,那么到底什么是资源,简单来讲,C#中的每一种类型都是一 ...
- 【转】C#中对IDisposable接口的理解
IDisposable接口定义:定义一种释放分配的资源的方法. .NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资 ...
- 【转】C# 的 IDisposable 接口
C# 的 IDisposable 接口 我在微软的团队快被微软 C# 里面的各种 IDisposable 对象给折腾疯了…… 故事比较长,先来科普一下.如果你没有用过 C#,IDisposable 是 ...
随机推荐
- MyBatis框架Maven资源
<!-- MyBatis框架 --> <dependency> <groupId>org.mybatis</groupId> <artifac ...
- javaSE之线程联合
首先定义 : 一个线程A在占有CPU资源期间 ,可以让其他线程调用join()和本线程联合. 嗯哈,像书本这个列子: 如: B.join(); 我们称A在运行期间联合了B, 如果线程A在占有CPU资源 ...
- 关于 iOS 批量打包的总结
关于 iOS 批量打包的总结 本文作者: 伯乐在线 - Tsui YuenHong .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 如果你曾经试过做多 target 的项目,到了测试人员要 ...
- useradd 和groupadd
1.作用useradd命令用来建立用户帐号和创建用户的起始目录,使用权限是终极用户.2.格式useradd [-d home] [-s shell] [-c comment] [-m [-k temp ...
- 用C#用C#实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码
run(){ while(true) { show(); if(条件) { ...
- POJ 1328 Radar Installation 贪心 难度:1
http://poj.org/problem?id=1328 思路: 1.肯定y大于d的情况下答案为-1,其他时候必定有非负整数解 2.x,y同时考虑是较为麻烦的,想办法消掉y,用d^2-y^2获得圆 ...
- 解决:操作无法完成(错误0x00000709)。再次检查打印机名称,并确保打印机已连接到.
就是重启一下服务器端的Print Spooler服务就行了,这么简单! [控制面板 - 服务 - Print Spooler]
- [转载]Android核心分析
2013-12-19 15:44:03 转载自: http://blog.csdn.net/column/details/androidcore.html 很好的文章,阅读请跳转到转载链接,转载备以后 ...
- Hibernate 错误处理
1. 在处理映射 1 对 n 时,Customer类为 1, Order类为 n,对象关系映射文件中没有错误,<many to one> 也正确,表名通类名. 但是,在执行插入时,发生两个 ...
- VS设置背景色减缓眼睛疲劳
工具--选项--字体和颜色--(纯文本)项背景色--自定义... 色调:85 饱和度:123 亮度:205 可自己微调 字体设为10.