c#处置模式
本文关键字:模式 | 更新日期: 2023-09-27 17:58:56
这里是一个典型的IDispose实现。我不明白的是析构函数?如果类的用户忘记调用Dispose,那么由于析构函数不会调用r1.Dispose(),难道不会发生资源泄漏吗?
public class DisposableObject : IDisposable
{
private bool disposed;
private UnmanagedResource r1;
public DisposableObject()
{
r1 = new UnmanagedResource();
}
~DisposableObject()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
// clean up managed resources
//call dispose on your member objects
r1.Dispose();
}
// clean up unmanaged resources
this.disposed = true;
}
}
public void SomeMethod()
{
if (this.disposed)
{
throw new ObjectDisposedException(this.GetType().FullName);
}
}
}
否-一旦对对象的所有引用都消失,GC将调用析构函数(但这不是确定性的)。
如果r1
真的是一个本地资源(在您的示例中看起来与它不同),则不应在If(displaying)块内部进行处理,而应在它之后进行处理。请特别注意:
if (disposing)
{
// free managed resources
if (managedResource != null)
{
managedResource.Dispose();
managedResource = null;
}
}
// free native resources if there are any.
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
从正确实现IDisposable-MSDN
如果r1
是一个托管资源,它有自己的IDisposable
实现,假设它实现正确,那么任何本机资源都将在其终结器中正确清理(这就是为什么您不需要在自己的终结器中担心它)。
析构函数(终结器)调用Dispose的原因是垃圾回收器在收集对象之前调用了它,从而保证至少在某个时刻UnmanagedResource将被释放。
通过使用using
和try...finally
,您可以在不需要时立即强制处理资源
http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
如果你真的想,你可以添加一个终结器:
~DisposeImplementation()
{
Dispose(false);
}
但它只能作为真正的最后手段,而不能直接依赖。
In。Net,我们有一个叫做垃圾回收的功能。垃圾回收会终结所有未被引用(不再被引用)的对象。然后,您的析构函数/终结器调用Dispose()。
如果您的用户忘记删除这些引用,您将以某种泄漏告终。但这正是using
的作用:通过仅在需求范围内定义一次性用品来避免内存堵塞。
模式存在是因为垃圾收集器不能保证托管对象被垃圾收集的顺序。因此,在终结器中,不能保证r1
引用仍然有效。
您的r1
引用的类名为UnmanagedResource
,但它显然是一个管理类型。对于一个真正的无人资源,您将只有一个IntPtr
或其他一些令牌。为了确保r1
不喜欢它的资源,它应该实现相同的Dispose模式,并在if (disposing)
检查之外释放它的非托管资源。