概要

C#提供了方便的垃圾回收机制,使我们几乎不再需要为资源管理费心。可事实上,能被垃圾回收释放掉的只是托管资源,非托管资源还是需要我们手动释放。而为了实现这一目的,C#提供了 IDisposable 接口,这篇文章就谈一谈 IDisposable 接口在使用中需要注意的地方。

实现

首先,IDisposable 接口非常简单,只包含一个方法 Dispose。在 IDisposable 接口的定义中可以看到明确的描述,它是用于释放非托管资源的 [1]。但是,想写出一个健壮的 IDisposable 实现却不是那么容易,好在微软为我们提供了一份详细的指南 [2][3],参照这份指南中的示例代码,我们就可以轻而易举的写出一份优秀的 IDisposable 接口实现代码了,这里不再进行详细说明。

那么那些资源是常见的非托管资源呢?根据我的经验,列举如下:

  • 文件流
  • 窗体句柄
  • 图片
  • 网络连接
  • 数据库连接

在使用到上述资源时,不要忘记务必在使用之后调用它们的 Dispose 方法。为了保证资源释放,一般我们会利用 try / finally 块,在 finally 块中调用 Dispose 方法。针对这种需求,C# 为我们提供了 using 语法糖 [4],对于实现了 IDisposable 接口的对象,利用 using 语句,可以简单的完成资源释放。

需要注意的细节

注意事件退订

当我们调用了一个对象的 Dispose 方法之后,它的非托管资源就被释放掉了,但是这个对象仍然可以被访问。因此,如果在这个对象内订阅了其他对象的事件,务必在 Dispose 方法中将事件退订 [5]。否则,事件发布者再次触发事件时,这个已经释放掉资源的对象还是会响应该事件,如果在事件响应方法中尝试访问已经释放的资源,则会发生意料外的错误。

WinForm 控件

从父容器中移除控件

当我们从一个容器中将某个控件 Remove 掉,这个控件的句柄并不会被释放,如果我们忘记显示地调用该控件的 Dispose 方法,又频繁地创建、移除控件,很快就会因为句柄过多而发生异常,面对这种情况,往往一头雾水,很难找到发生异常的根本原因。在以往的工作中,我一般会选择将一个控件从容器中 Remove 之后,再调用该控件的 Dispose 方法。后来无意间发现直接调用控件的 Dispose 方法,它会自动将自己从父容器中移除,通过阅读源码 [6] 证实了这个特性,真的挺方便。

移除自己的子控件

上面提到调用一个控件的 Dispose 方法,会自动将自己从父容器中移除。那么 Dispose 方法会对自己的子控件产生什么影响呢?是否需要在调用 Dispose 之前,先遍历并释放所有子控件呢?答案是不用,控件会自动调用所有子控件的 Dispose 方法,通过源码 [7] 可以证实这一点。可见,控件的 Dispose 方法是没有副作用的,一旦调用,就可以带着自己的资源,消失在我们的系统中,这种实现的思路,值得我们借鉴学习。

结语

IDisposable 为我们提供了便利,弥补了自动垃圾回收的不足,掌握好这个接口,不仅可以使我们的开发水平更进一步,也可以让我们的产品稳定性更上层楼。

参考文献:

[1] IDisposable 接口 (https://docs.microsoft.com/en-us/dotnet/api/system.idisposable?view=netframework-4.7.2#definition)
[2] 清理非托管资源 (https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/unmanaged?view=netframework-4.7.2)
[3] Dispose 模式 (https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern)
[4] using 语法糖 (https://docs.microsoft.com/en-us/dotnet/api/system.idisposable?view=netframework-4.7.2#the-c-and-visual-basic-using-statement)
[5] 取消订阅 (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events#unsubscribing)
[6] 从父容器中移除 (https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,6013)
[7] 自动释放子控件的资源 (https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,6017)

码农深耕 - 说说IDisposable的更多相关文章

  1. 【整理】待毕业.Net码农就业求职储备

    声明:本文题目来源于互联网,仅供即将从学校毕业的.Net码农(当然,我本人也是菜逼一个)学习之用.当然,学习了这些题目不一定会拿到offer,但是针对就业求职做些针对性的准备也是不错的.此外,除了技术 ...

  2. <开心一笑> 码农 黑客和2B程序员之间的区别

    笔记本电脑 码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L< ...

  3. 经典算法C++版(参考一线码农博文)

    鉴于一线码农的算法博文基本通过C#完成,此处用C++再实现一遍,具体解法可参考其博文. 地址:http://www.cnblogs.com/huangxincheng/category/401959. ...

  4. [2013 eoe移动开发者大会]靳岩:从码农到极客的升级之路

    (国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/) 前天,2013 eoe 移动开发者大会在国家会议中心召开,eoe 开发者社区创始人靳岩在 ...

  5. 专门为码农定制的14款创意的T裇(T-Shirt)设计

    T裇衫是人们在各种场合都可穿着的服装,如在T裇衫上作适当的装饰,即可增添无穷的韵味.通过图案直接反映人类的精神风貌,你可以把日常生活中的兴趣.习惯.喜怒哀乐.嗜好等展露无疑,张扬个性.秀出自我.对于码 ...

  6. 老码农教你在 StackOverflow 上谈笑风生

    作为一个高大上的码农,你肯定用到过 StackOverflow,必须的.会有人否定这个断言么?那他恐怕不是真正的码农,或者说还没入门.StackOverflow 对于码农的重要性,基本就和诸葛亮对刘备 ...

  7. 上不了Google是码农的悲哀

    http://refyt.com/?r=34d1edb7dba42e8d 上不了Google是码农的悲哀.1. 资料大部分都在国外的网站,差不多倍感伤心.2. Google Play没有办法访问了.3 ...

  8. .net 码农转战 iOS - 初探

    好久没写博客了,之前还打算把毕业设计中涉及到的两个算法拿出来说说(脸型分析 + 声音分析),博文都写了一半了,后来实在太忙了,那篇随笔也就沉在草稿列表中没动过. 我原先是专职 .net 开发的,在公司 ...

  9. IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)_互联网的一些事

    IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)_互联网的一些事 IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)

随机推荐

  1. 【转帖】云平台发现服务构建:为什么不使用ZooKeeper

    http://www.chinacloud.cn/show.aspx?id=19979&cid=16 [日期:2015-04-29] 来源:dockerone   作者: [字体:大 中 小] ...

  2. chome 离线安装包地址

    https://www.chromedownloads.net/chrome32win-stable/  --32bit https://www.chromedownloads.net/chrome6 ...

  3. android的通知栏的实现

    package com.example.mynotification; import android.os.Bundle; import android.app.Activity; import an ...

  4. IIS6 伪静态 IIS文件类型映射配置方法 【图解】

    1.右键点击 要设置网站的网站 2.属性 -->主目录 -->配置--> 3.如右侧窗口,找到 .aspx 扩展名-->编辑-->复制 可执行文件的路径-->关闭 ...

  5. atitit.提升兼容性最佳实践 o9o

    atitit.提升兼容性最佳实践 o9o.doc 1. Atitit.兼容性的"一加三"策略 1 2. 扩展表模式 1 3. 同时运行模式 1 3.1. 完美的后向兼容性 2 3. ...

  6. android studio 使用问题记录

    android studio 使用问题记录 下载地址:FQ或园子内好心人提供的国内地址: http://www.cnblogs.com/bjzhanghao/archive/2012/11/14/an ...

  7. Python 数据驱动ddt 使用

    准备工作: pip install ddt 知识点: 一,数据驱动和代码驱动: 数据驱动的意思是  根据你提供的数据来测试的  比如 ATP框架 需要excel里面的测试用例 代码驱动是必须得写代码  ...

  8. 安装CentOS版本的yum(转载)

    安装CentOS版本的yum 下载源:http://mirrors.163.com/centos/6/os/i386/Packages/ 材料准备: python-iniparse-0.3.1-2.1 ...

  9. CentOs下安装gcc/g++/gdb

    使用yum安装gcc:yum install gcc即可.使用:which gcc 查看是否安装成功 使用yum安装g++:yum install gcc-c++ 即可.使用:which g++ 查看 ...

  10. python学习笔记(11)--爬虫下载漫画图片

    说明: 1. 某本子网站爬虫,现在只实现了扒取一页,已经凌晨两点了,又饿又困,先睡觉,明天再写总结吧! 2. 我是明天,我来写总结了! 3. 这个网站的结构是这样的: 主页: 主页-第1页-漫画1封面 ...