C#中昂贵资源的释放是通过手工调用IDisposable.Dispose方法来进行的,更有using语句可以帮助用户及时调用Dispose方法,这在存在异常抛出的情况下非常有用。
class Demo : System.IDisposable
{
#region IDisposable 成员
public void Dispose()
{
throw new System.NotImplementedException();
}
#endregion }
Demo demo = new Demo();
// do something, but throw exceptions.
demo.Dispose();
Demo demo = new Demo();
try
{
// }
finally
{
demo.Dispose(); }
using (Demo demo = new Demo())
{
// do anything, even throw an exception. }
class Demo : System.IDisposable
{
private bool disposed = false;
#region IDisposable 成员
//可以被客户直接调用
public void Dispose()
{
//必须以Dispose(true)方式调用,以true告诉Dispose(bool disposing)函数是被客户直接调用的
Dispose(true); // MUST be true
// This object will be cleaned up by the Dispose method. Therefore, you should call GC.SupressFinalize to take this object off the finalization queue and prevent finalization co de for this object from executing a second time.
GC.SuppressFinalize(this); // 告诉垃圾回收器从Finalization队列中清除自己,从而阻止垃圾回收器调用Finalize方法.
}
#endregion
// 无法被客户直接调用
// 如果 disposing 是 true, 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放
// 如果 disposing 是 false, 那么函数是从垃圾回收器在调用Finalize时调用的,此时不应当引用其他托管对象所以,只能释放非托管资源
protected virtual void Dispose(bool disposing)
{
// If you need thread safety, use a lock around these operations, as well as in your methods that use the resource.
// Check to see if Dispose has already been called
if (disposed)
return;
if (disposing) // 这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放
{
// 在这里释放托管资源
}
// 在这里释放非托管资源
disposed = true; // Indicate that the instance has been disposed
}
// 析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用.默认情况下,一个类是没有析构函数的,也就是说,对象被垃圾回收时不会被调用Finalize方法
~Demo()
{
// 为了保持代码的可读性性和可维护性,千万不要在这里写释放非托管资源的代码
// 必须以Dispose(false)方式调用,以false告诉Dispose(bool disposing)函数是从垃圾回收器在调用Finalize时调用的
Dispose(false); // MUST be false
} }
class Demo : System.IDisposable
{
private bool disposed = false;
#region IDisposable 成员
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// TODO: 在这里释放托管资源
}
// TODO: 在这里释放非托管资源
disposed = true;
}
~Demo()
{
Dispose(false);
} }