码农深耕 - 说说IDisposable
概要
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的更多相关文章
- 【整理】待毕业.Net码农就业求职储备
声明:本文题目来源于互联网,仅供即将从学校毕业的.Net码农(当然,我本人也是菜逼一个)学习之用.当然,学习了这些题目不一定会拿到offer,但是针对就业求职做些针对性的准备也是不错的.此外,除了技术 ...
- <开心一笑> 码农 黑客和2B程序员之间的区别
笔记本电脑 码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L< ...
- 经典算法C++版(参考一线码农博文)
鉴于一线码农的算法博文基本通过C#完成,此处用C++再实现一遍,具体解法可参考其博文. 地址:http://www.cnblogs.com/huangxincheng/category/401959. ...
- [2013 eoe移动开发者大会]靳岩:从码农到极客的升级之路
(国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/) 前天,2013 eoe 移动开发者大会在国家会议中心召开,eoe 开发者社区创始人靳岩在 ...
- 专门为码农定制的14款创意的T裇(T-Shirt)设计
T裇衫是人们在各种场合都可穿着的服装,如在T裇衫上作适当的装饰,即可增添无穷的韵味.通过图案直接反映人类的精神风貌,你可以把日常生活中的兴趣.习惯.喜怒哀乐.嗜好等展露无疑,张扬个性.秀出自我.对于码 ...
- 老码农教你在 StackOverflow 上谈笑风生
作为一个高大上的码农,你肯定用到过 StackOverflow,必须的.会有人否定这个断言么?那他恐怕不是真正的码农,或者说还没入门.StackOverflow 对于码农的重要性,基本就和诸葛亮对刘备 ...
- 上不了Google是码农的悲哀
http://refyt.com/?r=34d1edb7dba42e8d 上不了Google是码农的悲哀.1. 资料大部分都在国外的网站,差不多倍感伤心.2. Google Play没有办法访问了.3 ...
- .net 码农转战 iOS - 初探
好久没写博客了,之前还打算把毕业设计中涉及到的两个算法拿出来说说(脸型分析 + 声音分析),博文都写了一半了,后来实在太忙了,那篇随笔也就沉在草稿列表中没动过. 我原先是专职 .net 开发的,在公司 ...
- IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)_互联网的一些事
IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)_互联网的一些事 IT码农哥放弃50万年薪:辞职卖咖喱凉皮(背后深藏功与名)
随机推荐
- 创建你的第一个Android PHP应用
google的开源移动操作系统Android给智能手机市场带来了风暴.不像Apple,对想要为水果市场(Iphone App Store)提供应用软件的开发者们有着严格的指导原则以及要求,Google ...
- 微信公众平台消息接口开发-封装weixin.class.php(转)
一.封装weixin.class.php 由于微信公众平台的通信使用的是特定格式的XML数据,每次接受和回复都要去做一大堆的数据处理. 我们就考虑在这个基础上做一次封装,weixin.class.ph ...
- 快速掌握Gif动态图实现代码
版权声明:本文为博主原创文章,未经博主允许不得转载. 前言:Gif一种动态图片,网上有很多制作这个的工具,包括PS都有,但作为一名程序员,我觉得如果自己通过编写代码把它实现,不但是对代码的掌握与复习, ...
- POJ 3279 Fliptile (二进制+搜索)
[题目链接]click here~~ [题目大意]: 农夫约翰知道聪明的牛产奶多. 于是为了提高牛的智商他准备了例如以下游戏. 有一个M×N 的格子,每一个格子能够翻转正反面,它们一面是黑色,还有一面 ...
- cordova添加Splash
最新版本的cordova添加Splash只需要改写config.xml 官方文档地址为:http://cordova.apache.org/docs/en/4.0.0/config_ref_image ...
- [转]IIS6 伪静态 IIS文件类型映射配置方法 【图解】
1.右键点击 要设置网站的网站 2.属性 -->主目录 -->配置--> 3.如右侧窗口,找到 .aspx 扩展名-->编辑-->复制 可执行文件的路径-->关闭 ...
- [Jobdu] 题目1408:吃豆机器人
题目描述: 淘宝公司内部有许多新鲜的小玩具,例如淘宝智能机器人.小时候,大家都玩过那个吃豆子的游戏吧,这机器人就是按照这个游戏设计的,它会朝着豆子的方向行走.不过机器人还存在一个bug,他只会朝南和朝 ...
- Android_WebServices_源代码分析
本博文为子墨原创,转载请注明出处! http://blog.csdn.net/zimo2013/article/details/38037989 在Android_WebServices_介绍一文中, ...
- vim中不同模式的帮助信息的查找
vim的模式有多种,比如normal(普通模式),insert(插入模式),command(命令行模式),visual(可视化模式).相同的命令和快捷键在不同的模式下功能是不一样的,因此帮助信息也是分 ...
- python 使用pyinstaller,pywin32打包.py成.exe应用程序
想将编写的Python代码在别人的电脑上运行,由于没有配置python的环境,这就有了困难.搜索学习了下,借助一定的工具可以将python程序的.py文件打包为exe文件,当然有多种方法,本文介绍的方 ...