public void Method()
{
var disposable = new DisposableObject();
}
DisposableObject是IDisposable。
在这种情况下,GC会自动调用Dispose方法吗?
答案 0 :(得分:3)
在这种情况下,GC会自动调用Dispose方法吗?
否。它不会调用Dispose
您必须自己调用它或使用using
阻止,即使发生异常也会确保将其处理。
using(var disposable = new DisposableObject())
{
//your code
}
IDisposable
用于确保在垃圾回收之前释放应用程序持有的非托管资源。由于GC
无法释放非托管资源(如文件处理程序)所持有的资源。
答案 1 :(得分:1)
没有GC不会对一次性对象(实现IDisposable的对象)调用Dispose。 GC通过调用托管对象的终结器(析构函数)来管理对象清理。 如果希望控制 >>管理资源被释放(而不是它们被释放),则实现Dispose方法。
例如,如果您有一个具有TCPClient成员的类,那么这是一个控制资源的托管对象 - 它所连接的端口。如果你没有在你的类上实现IDispose并且你使用了一个实例,那么当GC看到不再使用TCPClient时它会在某个时刻终止该对象并且端口将关闭 - 但是你无法控制WHEN发生。如果您需要访问端口和特定时间,那么您需要在关闭时进行控制 - 在这种情况下,您可以使用IDispose并使用using语句或直接调用Dispose以确保释放资源(端口)。
答案 2 :(得分:1)
如果某个类重写了一个名为Finalize
的方法,并且发现该类的实例在该实例上没有调用GC.SuppressFinalize()
时被放弃,那么GC将存储对该对象的引用一份Finalize
应该尽快运行的东西(暂时复活它)并标记该对象,以便下次放弃它时它就会消失。如果列表中已放置任何对象以立即完成,则GC将启动一个线程来运行其Finalize
方法。
无论出于何种原因,C#的创建者决定通过禁止程序员直接覆盖Finalize
而不是要求希望覆盖Finalize
的程序员使用他们称之为“析构函数”的构造来稍微混淆一些事情。 “,语法让人想起C ++析构函数,但完全不同的语义。虽然C#添加了一些包装代码,但通常可以认为~className {whatever}
大致相当于覆盖Finalize
。
Microsoft建议如果覆盖Finalize
(或实现C#析构函数),则覆盖/析构函数应该只调用签名为void Dispose(bool)
的方法,并为参数值传递False
。它基于这样的建议,即人们认为GC调用Dispose
。请注意,GC 本身不会调用Dispose
;进一步注意,大多数对象不应该实现C#析构函数,也不能以任何其他方式覆盖Finalize
。除非我们理解Finalize
涉及的所有极端案例,否则通常最好确保在对象被放弃之前{em}被调用