GC会自动调用dispose方法吗?

时间:2013-10-22 12:58:53

标签: c# .net idisposable disposable

public void Method()    
{
       var disposable = new DisposableObject();
}

DisposableObject是IDisposable。

在这种情况下,GC会自动调用Dispose方法吗?

3 个答案:

答案 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}被调用