可能重复:
Will the Garbage Collector call IDisposable.Dispose for me?
我有一个具有一些非托管资源的类。我的类实现了IDisposable
接口,并在Dispose()
方法中释放了非托管资源。我是否必须调用Dispose()
方法或以某种方式自动调用?垃圾收集器会调用它吗?
答案 0 :(得分:61)
Dispose()
不会自动调用。如果有终结器,它将自动调用。实现IDisposable
为类的用户提供了一种提前释放资源的方法,而不是等待垃圾收集器。
客户端的首选方法是使用using
语句来处理Dispose()
的自动调用,即使存在例外情况。
IDisposable
的正确实施是:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
如果该类的用户调用Dispose()
,则直接进行清理。如果垃圾收集器捕获了该对象,则会调用Dispose(false)
进行清理。请注意,从终结器(~MyClass
方法)调用时,托管引用可能无效,因此只能释放非托管资源。
答案 1 :(得分:6)
如果您在using
语句中实例化对象,则在代码退出using
块时为您调用Dispose()
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
如果您不使用using
,则由您(调用代码)通过明确调用Dispose()来处理您的对象。
此外,您(MyObject的实现者)可以在调用者不调用Dispose()的情况下添加对终结器的支持。更多信息here。
答案 2 :(得分:6)
为了确保正确处理资源,您需要在析构函数(终结器)中实现IDisposable
并调用Dispose
。
class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}
答案 3 :(得分:4)
你将手动调用此方法,可能在
之类的结构中using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed