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

C#Dispose模式相关推荐

  1. Effective C# 原则18:实现标准的处理(Dispose)模式(译)

    Effective C# 原则18:实现标准的处理(Dispose)模式 我们已经讨论过,处理一个占用了非托管资源对象是很重要的.现在是时候来讨论如何写代码来管理这些类占用的非内存资源了.一个标准的模 ...

  2. 利用C#实现标准的 Dispose模式

    我们已经知道了处置那些占用非受控(unmanaged)资源的对象的重要性,现在应该编写资源管理代码来处置那些包含非内存资源的类型了.整个.NET框架组件都使用一个标准的模式来处理非内存资源.使用你建立 ...

  3. C#中的Dispose模式

    C#中的资源 在我们的程序中,使用资源后,需要释放.那么在C#中的每一种资源,可以分为两类: - 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: - 非托管资源:不受CLR管理 ...

  4. C# Dispose模式

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

  5. 行动力决定了一个人的成败,有想法,就去做! C#的内存管理原理解析+标准Dispose模式的实现

    尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能的系统中高效地处理内存. C#编程的一个优点就是程序员不必担 ...

  6. 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源...

    建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...

  7. C# Dispose模式详细分析

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

  8. Effective C# Item18:实现标准Dispose模式

    如果一个类型中包含了非托管的资源,那么我们应该自己编写释放非托管资源的方法..NET提供了一个标准的用于释放资源的模式,叫做Dispose模式,在这种模式中,类型实现IDisposable接口,并提供 ...

  9. C#实现标准的Dispose模式

    上一章说过,对于对象包含非托管资源,要正确的加以清理.对于非托管资源来说,.net framework 会采用一套标准的模式来完成清理工作,因此,如果你编写的类里面用到了非托管资源,那么该类的使用者就 ...

最新文章

  1. 实训项目1-熟练使用VMware安装Windows server 2012
  2. Search For Mafuyu dfs,树的遍历,期望(济南)
  3. delete expired backup 和 delete obsolete
  4. python的环境变量设置
  5. html区块位置怎么设置,HTML 区块
  6. linux nfs4 超时,Linux文件服务器NFS详解【4】
  7. python输出文本内容_python如何输出文件内容
  8. 关于mapper接口与mapper.xml文件在同包运行找不到问题解决
  9. 西南财大计算机学院官网,西南财经大学
  10. MySQL反斜杠 ‘\\‘ 插入数据库丢失
  11. Python并行实现XML文件转换为XLSX文件
  12. 快40岁了,我还要不要继续写代码呢?
  13. python求学生成绩平均值_python 计算student_grade.txt 中 语文成绩的平均值, 找出数学成绩最高的学生是谁...
  14. 【转】纯JS省市区三级联动(行政区划代码更新至2015-9-30)
  15. 在PCLVisualizer中添加坐标轴和图片和颜色表
  16. 远程连接linux工具mob,ssh远程登录工具 mob,MobXterm与FileZilla
  17. 2018年校招深睿医疗面试
  18. B2G:来自Web平台的挑战者
  19. 手把手教你学python第十三讲(MRO详解和神奇的魔法方法)
  20. 摄影毁一生单反穷三代顺口溜_什么?这点预算你竟买了一套摄影设备!

热门文章

  1. weblogic集群部署
  2. 千兆以太网卡吞吐量和丢包率优化总结
  3. 效能评估系统解决方案
  4. 化合物分子可合成性打分 SA_Score;rdkit QED定量评估类药性
  5. 阿里云ECS lnmp linux7 安装mongodb连接不上 child process failed, exited with error number
  6. Outsmart Your Own Biases 战胜自己的偏见
  7. 现代图论Ⅰ(图论概念)
  8. Android 使用Rtmp音视频推流
  9. Python基础语法之while-else用法
  10. 自动监控网站消息动态并邮件通知 [附代码]