调用 Dispose() 与对象超出范围/方法完成时的比较
-
11-09-2019 - |
题
我有一个方法,其中有一个 try/catch/finaly
挡在里面。在 try 块中,我声明 SqlDataReader
如下:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
在里面 finally
块中,手动处理的对象是在类级别设置的对象。所以实现方法中的对象 IDisposable
, , 例如 SqlDataReader
如上所述,它们会被自动处置吗? Close()
被召唤 aReader
经过一段时间循环执行以获取阅读器的内容(应该是 Dispose()
正如那句话所说 Close()
)。如果没有电话 Close()
, ,当方法完成或对象超出范围时,该对象是否会自动关闭/处置?
编辑:我知道 using
声明,但有些场景让我感到困惑。
解决方案
不,对象超出范围时不会自动处置。
如果/当它们被垃圾收集时,它们甚至不能保证被处置,尽管许多 IDisposable
对象实现“后备”终结器以帮助确保它们最终被处置。
您有责任确保任何 IDisposable
物体被处置,最好将它们包裹在 using
堵塞。
其他提示
您应该使用using {...}
块包裹在IDisposable的对象 - Dispose()
方法(其为SqlDataReader的假冒到Close()
方法)using块结束时被调用。如果你不使用using
,对象将的不的自动当它超出范围设置 - 这将是对象最多终结,如果有的话,摆脱资源时,它是垃圾回收
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// ... do stuff
} // aReader.Dispose() called here
在Dispose模式不会使关于哪些对象将调用Dispose在其上的其他对象的任何保证;有时可能发生,但你不应该在乎。相反,它是你的责任,以确保Dispose()方法被调用所有IDisposable的对象。要做到这一点,最好的办法是与using
声明。例如:
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// your code
}
我同意所有上述的。你应该确保你叫Dispose()
自己,并以最简单的方法是用using
声明(你也可以自己做的finally
块 - 这是更详细的,但有时是必要的)。如果你不这样做,你可以找到你的应用程序泄漏非托管资源,如手柄,甚至非托管内存,特别是如果一个地方下的所有的这一些COM组件正在使用,或呼叫被制作成的Win32 API。这可以明显地导致性能和稳定性问题,以及过度的资源使用。
仅仅因为实现IDisposable
对象“应该”实现调用其Dispose(bool disposing)
方法来释放非托管资源finaliser,不能保证这会发生,所以你绝对不应该依赖于它。见,例如, http://msdn.microsoft的.com / EN-US /库/ b1yfkh5e%28VS.71%29.aspx 获得有关此点的详细信息。
此外,其他的东西要记住的是,如果你的类型有成员是一次性的,你的类型应该要么执行IDisposable
(除非这些成员的生命周期是由另一种类型,这显然可能会导致混乱管理),或,如果只在一个方法中使用这样的部件,或者实现的功能的一个特定部分,则应该考虑使得它们在使用它们的方法的局部变量/参数。
我被声明不解“在最后块,其被设置手动的对象是那些被设置在类级”。通过设置在类级别的对象,你的意思领域?你可能不应该是一个普通的方法中的这些处置,因为这样的字段的生命时间是不可预测的,取决于你碰巧有所谓的哪些方法。这将是更好地实现IDisposable,并在您的Dispose方法场处置。
可能会在使用声明帮助?