建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理

在标准的Dispose模式中,我们注意到一个以~开头的方法,如下:

        /// <summary>
/// 必须,防止程序员忘记了显式调用Dispose方法
/// </summary>
~SampleClass()
{
//必须为false
Dispose(false);
}

这个方法叫做类型的终结器。提供类型终结器的意义在于,我们不能奢望类型的调用者肯定会主动调用Dispose方法,基于终结器会被垃圾回收这个特点,它被用作资源释放的补救措施。

在.NET中每次使用new操作符创建对象时,CLR都会为该对象在堆上分配内存。对于没有继承IDisposable接口的类型对象,垃圾回收器则会直接释放对象所占用的内存:而对于实现了Dispose模式的类型,每次创建对象的时候,CLR都会将该对象的一个指针放到终结列表中,垃圾回收器在回收该对象的内存前,首先将终结列表中的指针放到一个freachable队列中。同时,CLR还会分配专门的线程读取freachable队列,并调用对象的终结器,只有这个时候对象才会真正被识别为垃圾,并且在下一次进行垃圾回收时释放对象所占的内存。

可见,实现了Dispose模式的类型对象,起码要经过两次垃圾回收才能真正地被回收掉,应为垃圾回收机制会安排CLR调用终结器。基于这个特点,如果我们的类型提供了显式释放的方法来减少一次垃圾回收,同时也可以在终结器中提供隐式清理,以避免调用者忘记调用该方法而带来的资源泄漏。

注意:有的文档中,终结器也称为析构器。析构器的叫法沿袭了C++中的称谓,因为两者形式非常接近,但两者实现机制还是不太一致,所以后来微软确定这个方法在C#中的名称为终结器。

如果调用者已经调用Dispose方法进行了显式地资源释放,那么,隐式资源释放(就是终结器)就没有必要再运行了。FCL中的类型GC提供了静态方法SuppressFinalize来通知垃圾回收器这一点。

        /// <summary>
/// 实现IDisposable中的Dispose方法
/// </summary>
public void Dispose()
{
//必须为true
Dispose(true);
//通知垃圾回收机制不再调用终结器(析构器)
GC.SuppressFinalize(this);
}

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

编写高质量代码改善C#程序的157个建议——建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

  2. 读书--编写高质量代码 改善C#程序的157个建议

    最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...

  3. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试

    建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...

  4. 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本

    建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...

  5. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  6. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

  7. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  8. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...

  9. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

随机推荐

  1. git常用命令小结

    1.ssh连接方式 公钥生成ssh-keygen -t rsa -C "764432054@qq.com"在用户家目录下的.ssh目录下生成 id_rsa ,id_rsa.pub ...

  2. java的Swing编程====实现鼠标双击一下==画图===getMouseClicked的方法

    总结: 使用匿名类,但是用实现接口的方式呢??? package com.aa; import java.awt.Color; import java.awt.Graphics; import jav ...

  3. AngularJS:简介

    ylbtech-AngularJS:简介 1.返回顶部 1. AngularJS 简介 AngularJS 是一个 JavaScript 框架.它可通过 <script> 标签添加到 HT ...

  4. mysql数据恢复 insert\update\delete 工具MyFlash

    一.简介MyFlash是由美团点评公司技术工程部开发维护的一个回滚DML操作的工具.该工具通过解析v4版本的binlog,完成回滚操作.相对已有的回滚工具,其增加了更多的过滤选项,让回滚更加容易. 该 ...

  5. Cassandra学习五 使用Key的正确姿势

    NoSQL一般是反范式的,比如提倡数据冗余,使得不至于写出非常复杂的SQL语句. Cassandra之中一共包含下面5中Key: Primary Key: 用来获取某一行的数据,可以是一列或多列   ...

  6. AD9如何设置原点位置

    Edit --> Origin --> Set

  7. 第九章 整合Mybatis(待续)

    ··········

  8. Centos安装php高版本

    安装 1.检查当前是否有安装php  rpm -qa|grep php 如果有安装PHP,那么请先删除这些安装包:  yum remove php* 2.安装php源 Centos 5 安装php源: ...

  9. Python中常见的异常处理

    异常和错误 part1:程序中难免出现错误,而错误分成两种 1. 语法错误(这种错误,根本过不了Python解释器的语法检测,必须在程序执行前就改正) # 语法错误示范一 if # 语法错误示范二 d ...

  10. javascript中的垃圾回收

    1引用计数垃圾回收 核心:跟踪记录对象被引用的次数.思路是如果一个对象A被赋值给了一个变量v,则该对象A的引用计数值加1,如果变量v又被赋予其他值了,比如a="str",则该对象A ...