C#关于垃圾回收 终结器IDispose的设计规范札记

Posted 圆孔里的方塞子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#关于垃圾回收 终结器IDispose的设计规范札记相关的知识,希望对你有一定的参考价值。

初学C#,在写winform程序时,常不进行资源释放,原本以为运行时会自动回收垃圾,直到有次关闭窗口后,发现打开的网口线程并未关闭,而是一直在后台收发数据。查找资料发现C#运行时的垃圾回收资源是有限定的。
垃圾回收功能旨在回收 不再被引用的对象所占的 内存,注意! 垃圾回收器只回收内存,不回收其他资源,如句柄(文件、窗口),网络端口,数据库连接,硬件设备。垃圾回收器根据是否存在访问不到的引用来决定清理内容,处理的是引用对象,只回收堆上的内存。
终结器允许程序员用写代码的方式来清理类的资源。终结器不负责回收内存,而负责释放像数据库连接和文件句柄这样的资源,这些资源需要通过一次显示的行动来清理。
下面设计规范摘录了一些书中的规范(C# 7.0本质论第10章内容):

  • 要只为使用了稀缺或昂贵资源的对象实现终结器方法,即使终结器会推迟垃圾回收。
  • 要为有终结器的类实现 IDisposable     接口以支持确定性终结。
  • 要为实现了 IDisposable     的类实现终结器方法,以防 Dispose () 没有被显示调用。
  • 要重构终结器方法来调用与 IDisposable     相同的代码,可能就是调用一下 Dispose () 方法。
  • 不要在终结器方法中抛出异常。
  • 要从   Dispose() 中调用     System.GC.SuppressFinalize() ,以使垃圾回收更快地发生,以避免重复性的资源清理。
  • 要保证 Dispose () 可以重入(可被多次调用)。
  • 要保持 Dispose()     的简单性,把重点放在终结所要求的资源清理上。
  • 避免为自己拥有的、带终结器的对象调用 Dispose () 。相反,依赖终结队列清理实例。
  • 避免在终结方法中引用未被终结的其他对象。
  • 要在重写Dispose() 时调用基类的实现。
  • 考虑在调用Dispose() 后将对象状态设为不可用。对象被dispose之后,调用除Dispose()     之外的方法应引发ObjectDisposedException 异常。
  • 要为含有可dispose 字段(或者属性)的类实现IDisposable接口,并dispose 这些字段引用的对象。
同时补充一些异常处理的设计规范
  • 只捕捉能处理的异常

  • 不要隐藏(bury)不能完全处理的异常

  • 尽量少用System.Exception     和常规 catch 块

  • 避免在调用栈较低的位置报告或者记录异常

  • 在catch块中使用throw; 而不是throw<异常对象> 语句

  • 想好异常条件来避免在catch块中重新抛出异常

  • 避免在异常条件表达式中抛出异常】

  • 避免以后可能变化的异常条件表达式

  • 重新抛出不同异常时要小心

  • 值意外为空时不要抛出 NullReferenceException, 而应抛出ArgumentNullException



以上是关于C#关于垃圾回收 终结器IDispose的设计规范札记的主要内容,如果未能解决你的问题,请参考以下文章

终结处理和垃圾回收

编写高质量代码改善C#程序的157个建议——建议52:及时释放资源

53.垃圾回收算法的实现原理启动Java垃圾回收Java垃圾回收过程垃圾回收中实例的终结对象什么时候符合垃圾回收的条件GC Scope 示例程序GC OutOfMemoryError的示例

Jvm垃圾回收器(终结篇)

12-JAVA清理_终结处理和垃圾回收

终结 finalize()和垃圾回收(garbage collection)