在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的更多相关文章

  1. C#中IDisposable学习

    在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...

  2. .NET中IDisposable接口的基本使用

    首先来看MSDN中关于这个接口的说明: [ComVisible(true)] public interface IDisposable { // Methods void Dispose(); } 1 ...

  3. C#中IDisposable的用法

    在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...

  4. C#中IDisposable的用法-垃圾回收

    在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...

  5. IDisposable接口

    C#中IDisposable接口的主要用途是释放非托管资源.当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存.但无法预测进行垃圾回收的时间.另外,垃圾回收器对窗口句柄或打开的文件和流等非托 ...

  6. TFS二次开发、C#知识点、SQL知识总结目录

    TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一个实例 TFS二次开发系列:四.TFS二次开发Wor ...

  7. TFS二次开发、C#知识点、SQL知识

    TFS二次开发.C#知识点.SQL知识总结目录   TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一 ...

  8. Core官方DI解析(2)-ServiceProvider

    ServiceProvider ServiceProvider是我们用来获取服务实例对象的类型,它也是一个特别简单的类型,因为这个类型本身并没有做什么,其实以一种代理模式,其核心功能全部都在IServ ...

  9. Python开源框架

    info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...

随机推荐

  1. HDU 3339 最短路+01背包

    In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. JAVA基础--容器 Set, List, Map

    Colections接口, Iterator接口, Set接口, List接口, Comparable接口, Map接口 Collections类 容器:装各种对象. 所有容器都在java.util里 ...

  3. mariadb cache

    Since MariaDB Galera cluster versions 5.5.40 and 10.0.14 you can use the query cache. Earlier versio ...

  4. 第四弹:overfeat

    overfeat是在AlexNet出现后,推出来的模型,其不仅用于物体分类,来用于定位,检测等,可以说是一个涉及很多应用场景的通用模型,值得看看. 本文将从两个方面来讲解,第一部分从论文角度来说一说, ...

  5. DHCP配置部分

    1.DHCP工作过程 dhcp discover \\客户端请求服务器器提供地址 dhcp offer \\服务器提供ip地址 dhcp request \\客户端租用ip地址 dhcp ack \\ ...

  6. $(srctree) is not clean, please run 'make mrproper'

    在使用make menuconfig重新配置后,再编译kernel时常会遇到这样的问题: Using /home/likewise-open/BJS/lisa.liu/code/sprdroid4.0 ...

  7. 微信小程序tips集合:无法输入文字/随时查看页面/元素审查/点击事件/数据绑定

    1:编辑文档无法输入文字 出现这种情况一般是因为之前编辑的文档未保存,所有在其他文档输入的时候会自动输入到未保存的文档中,在文档暂时编辑完毕后要ctrl+s随手保存,不然会出现无法打字情况 2: 随时 ...

  8. Android编程中的5种数据存储方式

    Android编程中的5种数据存储方式 作者:牛奶.不加糖 字体:[增加 减小] 类型:转载 时间:2015-12-03我要评论 这篇文章主要介绍了Android编程中的5种数据存储方式,结合实例形式 ...

  9. Sequence Classification

    Natural Language Processing with Python Charpter 6.1 import nltk from nltk.corpus import brown def p ...

  10. ajax常用写法

    $.ajax( url,{ type:"post", data:{},}) .done(function() { alert("success"); }) .f ...