下面是一个典型的dispose模式示例:
public bool IsDisposed { get; private set; }
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
//perform cleanup here
}
IsDisposed = true;
}
}
~MyObject()
{
Dispose(false);
}
我理解dispose的作用,但我不理解的是为什么要在析构函数中调用dispose(false)?如果你看看它的定义,它绝对不会做任何事情,那么为什么会有人写这样的代码呢?完全不从析构函数调用dispose不是很有意义吗?
发布于 2009-03-10 03:11:24
终结器被用作后备,如果由于某种原因对象没有被正确地处理。通常,将调用Dispose()
方法,该方法将移除终结器挂钩,并将对象转换为垃圾回收器可以轻松移除的常规托管对象。
下面是一个来自MSDN的示例,其中包含要清理的托管和非托管资源。
请注意,只有在disposing
为true时,才会清理托管资源,但始终会清理非托管资源。
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
private bool disposed = false;
// The class constructor.
public MyResource(IntPtr handle)
{
this.handle = handle;
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(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 code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
发布于 2009-03-10 02:53:25
C#中没有析构函数。这是一个终结器,这是另一回事。
区别在于您是否需要清理托管对象。你不会想要在终结器中清理它们,因为它们本身可能已经完成了。
我最近碰巧浏览了C#编程指南的Destructors页面。这表明我在上面的回答中是错误的。特别是,析构函数和终结器之间有一个区别:
class Car
{
~Car() // destructor
{
// cleanup statements...
}
}
等同于
protected override void Finalize()
{
try
{
// Cleanup statements...
}
finally
{
base.Finalize();
}
}
发布于 2009-03-10 02:59:48
在if(disposing)中,你应该在拥有非托管资源(例如数据库连接)的托管对象上调用dispose/close .When,终结器被称为终结器,这些对象不再可达,因此对象本身可以被终结,你不需要对它们调用dispose。另外,终结的顺序是不确定的,因此您可能会在已经释放的对象上调用dispose。
https://stackoverflow.com/questions/628752
复制相似问题