很久以前来自C / C ++我仍然习惯于确保所有资源都得到正确清理。我总是确保在IDisposable类上调用Dispose,并在包含一次性对象的类中实现Dispose模式。
然而,在我的环境中,我或多或少是唯一一个这样做的人。其他人只是不明白我在做什么,并认为我的代码更难理解。
他们只是创建数据库连接,打开流等而不调用Close或Dispose。有时他们会在方法结束时将本地或成员变量设置为“Nothing”(猜测其背景)。
我的问题是他们的代码和我的代码一样好用。随着时间的推移创建数千个数据库连接对象的代码才能正常工作。
所以,忽略关于代码正确性的任何争论,遵循指南等, IDiposable真的重要吗?
是否有人实际上没有使用Disposing对象的资源?
修改: 感谢所有回复。有趣的是,有些人在没有处理时遇到了问题。这似乎很少见,我认为GC / JIT在正常条件下保持资源使用率下降方面做得很好。
我的同事和我都不会因为这个而改变行为,但是对你来说感觉很好。
答案 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作为你的拐杖。