我们使用Enterprise Library 3.0访问Oracle DB(microsoft oracle客户端)。 在调用存储过程或函数后不处理DbCommand实例时会发生什么? .NET会自动垃圾收集吗? 请注意,我们确保事务/连接已关闭并正确处理。
答案 0 :(得分:19)
这是重复的,但我没有时间找到原文。
如果它实现了IDisposable,并且你创建了它,那么你需要在它上面调用Dispose。这就是为什么该类的开发人员使它实现IDisposable。
垃圾收集器不会对所有IDisposable实现对象调用Dispose。
答案 1 :(得分:7)
Reflector并不表示OracleCommand
明确地覆盖了Dispose(来自System.ComponentModel.Component
的实现),所以如果你不调用它,它很可能不会伤害你的应用程序。
重要的是,OracleCommand
专门实现了IDbCommand
,它专门实现了IDisposable
。如果您曾将OracleCommand
替换为另一个IDbCommand
,那么您很可能希望使用Dispose()
。虽然SqlCommand
没有显式覆盖Dispose()
,但Odbc和OleDb肯定会这样做。
简而言之,因为它是IDisposable
,所以你应该处理它,只是为了安全起见。
答案 2 :(得分:4)
来自IDisposable
的文档:
此接口的主要用途是释放非托管资源。当不再使用该对象时,垃圾收集器会自动释放分配给托管对象的内存。但是,无法预测垃圾收集何时发生。此外,垃圾收集器不了解非托管资源,例如窗口句柄,或打开文件和流。
使用此接口的Dispose方法与垃圾收集器一起显式释放非托管资源。当不再需要该对象时,对象的使用者可以调用此方法。
鉴于此,实现IDisposable
的对象可能会维护对非托管资源的引用。在垃圾收集器出现并收集对象之前,不会释放这些资源。但是,由于您无法知道垃圾收集器何时执行此操作,因此一次性对象(例如OracleDbCommand
)可能会比您希望的更长时间停留。
如果某个对象实现了IDisposable
,那么应该尽快调用它来释放它所持有的非托管资源。这可以通过直接调用Dispose
或在使用块中声明它来完成。
答案 3 :(得分:1)
不是100%确定Oracle,但在使用SqlCommand时,必须在使用后进行处理。您可以只调用.Dispose(),或者只是将它放在using块中,如下所示:
using(DbCommand cmd = new DbCommand(foo, bar))
{
// use cmd object
}