C#Dispose模式

  • 目的:

    为了及时释放宝贵的非托管资源和托管资源,并且保证资源在被gc回收的时候可以正确释放资源,同时兼顾执行效率

  • 必须遵循的事实:

1 托管资源释放:
  由另一线程的gc进行释放,当托管的对象没有被引用时,就会在“适当的时候”进行回收
  如果定义了析构函数,回收的时候会调用析构函数(实际执行可能有差别),之后释放对象占用的内存。
  当类有析构函数时, gc会分分两步来释放,如果没有析构函数或者指定不需要调用析构函数时,只需要一步就能释放

2 非托管资源必须显式释放

  • 方案:

1.把资源释放都放在析构函数里。

可以保证资源都释放,但是由于gc调用时机的不确定性,导致宝贵的非托管资源无法及时释放。

2. 写个释放函数,手动是调用

如果忘了释放的话, 托管资源会被gc释放,但非托管资源就无法释放

3. Dispose模式。参考下面的代码

手动调用Dispose() 可以释放所有资源,并且在gc标记不需要再调用析构函数,从而提高了效率。

如果忘记调用Dispose(), 则当gc调用析构函数的时候也会把非托管资源释放掉

-------参考代码-----------

public interface IDisposable
{void Dispose();
}
public class DisposablClass : IDisposable
{//是否回收完毕bool _disposed;public void Dispose(){Dispose(true);GC.SuppressFinalize(this); //标记gc不在调用析构函数
    }~DisposableClass(){Dispose(false);}private void Dispose(bool disposing){if(_disposed) return; //如果已经被回收,就中断执行if(disposing){//TODO:释放本对象中管理的托管资源
        }//TODO:释放非托管资源_disposed = true;}
}

  • 可能存在的疑问

    1. 既然gc是另外一线程执行的,为什么Dispose(bool)函数里不加锁?
     答:因为如果可以主动调用的时候,肯定此对象不是死对象,也不会被回收,因此不会同时调用到

    2. 为什么析构函数调用的dispose(false)不释放托管资源?
        答:因为析构函数由gc来调用,gc会依次释放所有的死对象(不可到达),释放的顺序是随机的,如果在一个对象的析构里调用了一个本次gc已经释放的对象,就会发生释放两次的错误。

  • 这个讲的也不错,就是有点啰嗦:

    https://blog.csdn.net/zrf2112/article/details/50644652

转载于:https://www.cnblogs.com/xyzf/p/9021513.html

C# Dispose模式详细分析相关推荐

  1. dispose 模式 java_C# Dispose模式详细分析

    C#Dispose模式 目的: 为了及时释放宝贵的非托管资源和托管资源,并且保证资源在被gc回收的时候可以正确释放资源,同时兼顾执行效率 必须遵循的事实: 1 托管资源释放: 由另一线程的gc进行释放 ...

  2. java消费者模式_基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相 ...

  3. java生产线消费者,基于Java 生产者消费者模式(详细分析)

    生产者消费者模式是多线程中最为常见的模式:生产者线程(一个或多个)生成面包放进篮子里(集合或数组),同时,消费者线程(一个或多个)从篮子里(集合或数组)取出面包消耗.虽然它们任务不同,但处理的资源是相 ...

  4. Java 代理模式的实现和原理详细分析

    文章目录 代理模式 静态代理 1. 静态代理的概念 2. 静态代理的实现 动态代理 1. 动态代理的概念 2. 动态代理的实现 2.1 如何创建一个动态代理对象 2.2 完整的动态代理的例子 3.动态 ...

  5. 详细分析Apple macOS 6LowPAN 漏洞(CVE-2020-9967)

     聚焦源代码安全,网罗国内外最新资讯! 安全研究员 Alex Plaskett 在2020年5月向苹果报告了影响MacOS Big Sur 的一个漏洞 (CVE-2020-9967).苹果公司在12月 ...

  6. android 串口开发_详细分析Esp8266上电信息打印的数据,如何做到串口通讯上电不乱码打印...

    01 写在前面: 上篇关于如何在内置仅1M的Esp8285做到 OTA 升级的同步到微信公众号,竟然被安信可的某些运维人员看到了,想要转载,我很欣慰,竟然自己的笔记可以被这么大型的公司员工认可! 我是 ...

  7. 处理大并发之四 libevent demo详细分析(对比epoll)

    处理大并发之四 libevent demo详细分析(对比epoll) libevent默认情况下是单线程,每个线程有且仅有一个event_base,对应一个struct event_base结构体,以 ...

  8. arm中断保护和恢复_ARM中断返回的详细分析

    原标题:ARM中断返回的详细分析 在ARM体系中,通常有以下3种方式控制程序的执行流程: 1.在正常执行过程中,每执行一条ARM指令,程序计数器PC的值加4个字节:每执行一条Thumb指令,程序计数器 ...

  9. s3c2440启动文件详细分析

    启动文件就是引导ARM启动,并进入我们熟悉的C语言程序.它主要完成了ARM最基本的硬件初始化工作.虽然启动文件的内容大同小异(就是设置系统时钟.内存.中断向量表.栈等内容),而且只要有一个现成的启动文 ...

最新文章

  1. IT草根的江湖之路之六:曙光,第一次破例
  2. ArcIMS 投影问题 如何向地图配置文件中添加投影信息(转载)
  3. 对 makefile 中 $(MAKE) 的学习体会
  4. 为什么apm代购价那么便宜_为什么长焦相机那么便宜而单反相机那么贵
  5. 华为手机如何调时间显示_华为手机照片如何出现时间地点天气,教你30秒,一学就会...
  6. 云吟职中计算机老师,夹江县云吟职业中学校018招生简介
  7. gatsby_什么是环境变量?如何在Gatsby和Netlify中使用它们?
  8. 代码大全(第二版)笔记——高质量的子程序
  9. mui toast自定义样式
  10. mysql 一对多查询组成单表字段_单表多字段MySQL模糊查询的实现
  11. enterprise architect mysql_Enterprise Architect 8之数据建模(创建表) | 学步园
  12. IE 11下载文件中文乱码解决(go/php)
  13. linux系统怎么连接显示器,Linux下笔记本外接显示器 · Eulerlee
  14. 科技人才开发效率的空间杜宾模型分析
  15. 电脑上怎么查看邮件服务器,教您如何查看电子邮件头 -电脑资料
  16. 【Android App】实战项目之虚拟现实(VR)的全景相册(附源码和演示视频 可用于学习和大作业)
  17. 使用Visual Studio Code进行ABAP开发
  18. MySQL 数据库死锁问题-Deadlock found when trying to get lock
  19. 微机原理DOSBox安装与使用
  20. go语言生成ssl证书

热门文章

  1. matlab怎么看输出电压纹波,教你如何正确取电源的输出纹波噪声值
  2. MySQL使用什么关键字添加唯一约束_mysql怎么添加唯一约束?
  3. python中如何计算集合的长度_Python如何计算序列长度 python dataframe中元素如何统计?...
  4. Vue3 + cli4 配置路由
  5. 两台linux电脑怎么互推文件夹,Llinux文件目录权限及chmod命令简析
  6. android ril.java_Android RIL的java框架
  7. js文件中可以写html吗,js代码写在HTML正常,分离成js文件再在HTML中引用不起作用...
  8. clickhouse 的mysql表引擎
  9. VB 屏幕融化超级恶搞程序代码
  10. Windows自启动程序的十大藏身之所