调用Dispose()vs对象超出范围/方法完成
我有一个方法,里面有一个try / catch / finall块。 在try块中,我声明SqlDataReader如下:
SqlDataReader aReader = null; aReader = aCommand.ExecuteReader();
在finally块中,手动处理的对象是在类级别设置的对象。 那么实现IDisposable的方法中的对象,比如上面的SqlDataReader,它们会被自动处理掉吗? 在while循环执行后,在aReader上调用Close()以获取读取器的内容(应该是Dispose(),因为它调用Close())。 如果没有调用Close(),当方法完成或对象超出范围时,是否会自动关闭/处置此对象?
编辑:我知道using()语句,但有些情况让我感到困惑。 谢谢
谢谢
不,当对象超出范围时,它们不会自动处理。
如果/当它们被垃圾收集时,它们甚至不能保证被处置,尽管许多IDisposable
对象实施“后备”终结器以帮助确保它们最终被处置。
您有责任确保处置任何IDisposable
对象,最好将它们包装在using
块中。
您应该使用using {...}
块来包装您的IDisposable对象 – 当using块结束时,将调用Dispose()
方法(SqlDataReader传递给Close()
方法)。 如果你不使用,当对象超出范围时,对象将不会被自动处理 – 如果有对象终结器,它将取决于垃圾收集时的资源。
using (SqlDataReader aReader = aCommand.ExecuteReader()) { // ... do stuff } // aReader.Dispose() called here
Dispose模式不保证哪些对象将调用Dispose来处理其他对象; 它有时会发生,但你不应该在乎。 相反,您有责任确保为所有IDisposable对象调用Dispose()。 using
语句的最佳方法是使用using
语句。 例如:
using (SqlDataReader aReader = aCommand.ExecuteReader()) { // your code }
我同意以上所有内容。 您应该确保自己调用Dispose()
,最简单的方法是使用using
语句(您也可以在finally
块中自己执行此操作 – 这更详细,但有时是必要的)。 如果你不这样做,你会发现你的应用程序泄漏了非托管资源,如句柄,甚至非托管内存,特别是如果正在使用所有这些COM组件下面的某个地方,或者正在调用Win32 API。 这显然会导致性能和稳定性问题,以及过多的资源使用。
仅仅因为实现IDisposable
对象“应该”实现调用其Dispose(bool disposing)
disposing Dispose(bool disposing)
方法来释放非托管资源的终结器,并不能保证会发生这种情况,所以你绝对不应该依赖它。 例如,有关此点的更多信息,请参阅http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx 。
此外,还要注意的是,如果您的类型具有一次性的成员,您的类型应该实现IDisposable
(除非这些成员的生命周期由另一种类型管理,显然可能会变得混乱),或者,如果您只在一个方法中使用这些成员,或者为了实现一个特定的function,你应该考虑在使用它们的方法中使它们成为局部变量/参数。
我对这句话感到困惑“在最后一个块中,手动处理的对象是那些在类级别设置的对象。” 通过在类级别设置的对象,您的意思是字段吗? 您可能不应该在普通方法中处理这些,因为那时字段的生命周期是不可预测的,并且取决于您碰巧调用的方法。 最好在Dispose方法中实现IDisposable和处理字段。
使用语句有帮助吗?