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);
            }
        }
    }

c#处置模式

否-一旦对对象的所有引用都消失,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将被释放。

通过使用usingtry...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)检查之外释放它的非托管资源。