当前位置: 华文问答 > 数码

C# 里的 dispose 的作用是什么?

2019-06-13数码

对于托管资源交给gc就可以,但是对于非托管资源你需要手动确定时机因为系统没办法知道时机。举个例子,比如网络连接,你可以用完就断开也可以用几年才关,gc是没有办法通过标记垃圾回收的引用规则真正知道你什么时候用完,只有开发者才知道。

另外一类的资源是需要马上释放的,底层的实现很多是native调用的,比如文件句柄,还有底层的设备接口等。那种东西之所以需要被设计成可以马上释放,是因为他们具有独占性影响,比如你的文件加了文件锁那么理论上这一刻别的进程,不是你的app对它写而期待读怎么办?而gc是设计成希望开发者不关注被触发的时机来响应的处理。但是文件访问很可能是你用完别人马上要用这个文件哇。我们想象这样一种情景,比如你本地有2个exe运行,a.exe负责生成一些中间数据,然后b.exe从这些中间文件读数据来做别的处理逻辑。假设a.exe和b.exe是不同的进程,并且通过socket通讯。a处理完了,保存完了数据告诉b.exe你可以干活了。然后这个时候a由于不知道什么时候触发gc,所以不知道什么能释放这个文件的使用权。然后你明明通知了b.exe可以干活了。

结果b.exe等了半天,好没好哇兄弟。结果你憋了半天硬是没触发gc而释放文件句柄。你说这样的设计蛋疼不?

你可能说,我自己hack一下自己调用一下System.GarbageCollection()哇。别做这种蠢事!如果你写java,c#还需要手动调用gc,那么说明这个程序有毒。你真正需要的是调用handle.Close()或者handle.Dispose()!

你不要把c#的世界理解为只有c#哇,实际上你还要合c++等其他环境开发的系统组件有交互呢。还有你要和别的进程交互呢,你怎么跨进程控制gc的东西?那么有没有多个进程竞争访问资源的情况?事实上是有的哇。gc能解决一部分问题,但绝对不是全部。