调用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和处理字段。

使用语句有帮助吗?