IDisisposable,它真的很重要

时间:2010-03-17 19:39:09

标签: .net resources idisposable

很久以前来自C / C ++我仍然习惯于确保所有资源都得到正确清理。我总是确保在IDisposable类上调用Dispose,并在包含一次性对象的类中实现Dispose模式。

然而,在我的环境中,我或多或少是唯一一个这样做的人。其他人只是不明白我在做什么,并认为我的代码更难理解。

他们只是创建数据库连接,打开流等而不调用Close或Dispose。有时他们会在方法结束时将本地或成员变量设置为“Nothing”(猜测其背景)。

我的问题是他们的代码和我的代码一样好用。随着时间的推移创建数千个数据库连接对象的代码才能正常工作。

所以,忽略关于代码正确性的任何争论,遵循指南等, IDiposable真的重要吗

是否有人实际上没有使用Disposing对象的资源?

修改: 感谢所有回复。有趣的是,有些人在没有处理时遇到了问题。这似乎很少见,我认为GC / JIT在正常条件下保持资源使用率下降方面做得很好。

我的同事和我都不会因为这个而改变行为,但是对你来说感觉很好。

9 个答案:

答案 0 :(得分:26)

是的,我在循环连接对象时最大化了Oracle游标的数量,例如,因为我忘了关闭命令阅读器 - 在单个连接上也只有100个循环,我需要支持可能有数百个连接在同一时间完成它。

如果他们无法自己关闭任何非托管资源,那么应该教你的开发人员使用using() { ... } syntax 。无论如何这都是很好的做法,你也应该使用它,因为你自己可能忘记将Dispose()调用放在finally {}子句中,以便在发生未处理的异常时真正清理它

如果你无法赢得他们的心 - 改变他们的想法 - 创建测试,通过最大限度地消除他们没有清理的资源来破坏他们的代码 - 然后表明“修复”简单易行,并启用他们的代码更具可扩展性。或者只是向老板展示并告诉他们这将使他/她能够将产品作为新版本销售,并且内置更多可扩展性:)您的开发人员将被指示将来一直这样做,希望和你也会受到更多的关注。

答案 1 :(得分:5)

是的,这很重要。当一个对象实现IDisposable时,显式声明它正在保存当不再需要该对象时需要释放的资源。

当对象最终确定时,大多数人仍然会清理他们的资源,但最终确定不是确定性的,不能依赖于资源管理。

简单地将变量声明包装在using(...)块中可以很容易地正确处理。

答案 2 :(得分:4)

其中一些资源(如句柄)是整个系统的有限资源,因此如果您的应用程序不释放这些其他应用程序,甚至操作系统可能会受到影响。看看Mark Russinovich的latest article在推动Windows系列的限制中的例子。

答案 3 :(得分:3)

是的,我也遇到了一个问题,连接对象到Oracle数据库没有被处理掉。

迈克阿特拉斯上面的问题很糟糕,但至少可以清楚地知道出了什么问题。我们遇到的问题是,在我们试图打开连接时,网站会不时地在重负载下开始抛出错误,但是当我们查看系统时它已经全部清除(因为garabe收集器已经清除)对象并释放连接池)。重复之前很难重现,直到我查看代码并注意到在发生错误时没有关闭连接,将其更改为using语句修复了整个问题。

简短的回答是,如果某个对象需要付出努力来实现IDisposable,那么它就是有原因的,所以在完成后总是处理它,理想情况下使用using语句。有时处理时不要聪明或狡猾,但有时候你不认为你需要等等等等。只做每次都有效的事情。

更短,更令人满意的答案是,你是对的,你的同事是不知道自己在做什么的蠢货。

答案 4 :(得分:1)

不处理(或关闭)数据库连接最终会咬你,是的。我已经看到了这种情况。

答案 5 :(得分:0)

我有一个案例,遗憾的是我不记得细节,但它是某种分层流。在刷新上层文本格式化程序之前,有时会关闭较低级别的文件流,这会导致写入文本格式化程序的最后一个输出丢失。

答案 6 :(得分:0)

不处理数据库相关的IDisposable对象是在环境中生成OutOfMemoryExceptions的可靠而有效的方法。

DataSet实现了IDisposable,我读过没有必要调用Dispose,因为只需要在设计时(由visual studio designer)创建需要为数据集处理的对象。我从未在Un-Disposed数据集中看到过OOM(只是来自巨大DataSet的OOM)

答案 7 :(得分:0)

除了资源耗尽的明显情况(已经提及)之外,IDisposable的另一个好处是,因为它保证在using块退出时调用Dispose(),所以你可以将它用于各种类型的事情,甚至不仅仅是“使用OS资源执行操作”的事情。

通过这种方式,它就像一个穷人替代Ruby块,或者用于Lisp宏的一个小用例。

答案 8 :(得分:0)

是,是,是,这很重要。

我最近一直在分析一个从未被描述过的应用程序。它只是一个Winforms应用程序,没什么大不了的,对吧?

错误。

通过不实现IDisposible而不是取消引用事件处理程序,应用程序就像筛子一样泄漏内存。

  

.NET Framework并不能免除你自己清理的麻烦,只是如果不这样做,它就会减少你破坏的可能性。

花一小时,使用ANTS Profiler对您的申请进行分析。这是一个免费试用版。如果您没有看到任何内存泄漏,请继续。如果你这样做,那是因为你依靠.NET Framework作为你的拐杖。