C# 当对象超出范围/方法完成时调用Dispose()vs
我有一个方法,里面有一个C# 当对象超出范围/方法完成时调用Dispose()vs,c#,idisposable,using,using-statement,C#,Idisposable,Using,Using Statement,我有一个方法,里面有一个try/catch/finaly块。在try块中,我声明SqlDataReader,如下所示: SqlDataReader aReader = null; aReader = aCommand.ExecuteReader(); 在finally块中,手动处理的对象是在类级别设置的对象。那么,在方法中实现IDisposable的对象,比如上面的SqlDataReader,它们会被自动处理吗关闭()在执行while循环以获取读卡器的内容(调用关闭()时应
try/catch/finaly
块。在try块中,我声明SqlDataReader
,如下所示:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
在finally
块中,手动处理的对象是在类级别设置的对象。那么,在方法中实现IDisposable
的对象,比如上面的SqlDataReader
,它们会被自动处理吗<代码>关闭()在执行while循环以获取读卡器的内容(调用关闭()
时应为Dispose()
)后,在区域der上调用。如果没有调用Close()
,当方法完成或对象超出范围时,是否会自动关闭/处置此对象
编辑:我知道using
语句,但有些场景让我感到困惑。您应该使用using{…}
块将IDisposable对象包装在中-using块结束时将调用Dispose()
方法(对于SqlDataReader,该方法传递到Close()
方法)。如果不使用
使用,则对象超出范围时将不会自动处理-垃圾收集时,将由对象终结器(如果有)来清除资源
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// ... do stuff
} // aReader.Dispose() called here
该语句是否有帮助?Dispose模式不能保证哪些对象将对哪些其他对象调用Dispose;有时候可能会发生,但你不应该在意。相反,您的责任是确保为所有IDisposable对象调用Dispose()。最好的方法是使用
语句。例如:
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// your code
}
不,对象超出范围时不会自动释放
它们甚至不能保证在被垃圾收集时被释放,尽管许多IDisposable
对象实现了一个“回退”终结者来帮助确保它们最终被释放
您有责任确保处置任何IDisposable
对象,最好是将它们包装在一个块中。我对“在最后一个块中,手动处置的对象是在类级别设置的对象”这句话感到困惑。在类级别设置的对象是指字段吗?您可能不应该在普通方法中处理这些字段,因为字段的生命周期是不可预测的,并且取决于您碰巧调用了哪些方法。最好在dispose方法中实现IDisposable和dispose字段。我同意上述所有观点。您应该确保自己调用Dispose()
,最简单的方法是使用语句调用(您也可以在finally
块中自己调用-这更详细,但有时是必要的)。如果不这样做,您可能会发现应用程序正在泄漏非托管资源,例如句柄,甚至非托管内存,尤其是在所有这些资源下面的某个地方正在使用某些COM组件,或者正在调用Win32 API。这显然会导致性能和稳定性问题,以及过度的资源使用
仅仅因为实现IDisposable
“应该”实现调用其Dispose(bool disposing)
方法释放非托管资源的finalizer,并不保证会发生这种情况,所以您绝对不应该依赖它。例如,有关这一点的更多信息,请参见
另外,还需要记住的一点是,如果您的类型具有可丢弃的成员,则您的类型应该实现IDisposable
(除非这些成员的生命周期由另一个类型管理,这显然可能会变得混乱),或者,如果您仅在一种方法中使用这些成员,或者为了实现一个特定的功能,应该考虑使用它们的方法中的局部变量/参数。