繁体   English   中英

如果我的类实现了 IDisposable,为什么我需要终结器?

[英]Why do I need a finalizer if my class implements IDisposable?

下面的一次性图案呢?

using System;
public class MyClass : IDisposable 
{     
    public void Dispose() 
        // Implement IDisposable     
    {
        //just do the cleanup
        GC.SuppressFinalize(this);
    } 

} 

更新

我的意思是说,如果没有非托管资源,我是否需要终结器? 上面的一次性图案还不够好吗? 是的,即使用户/开发人员不调用 dispose,GC 是否默认不调用 dispose?

那么GC调用dispose和finalizer的顺序呢?

有关更多详细信息,请参阅此问题

换句话说,当我们有终结器时,为什么我们以 false 为参数调用Dispose


http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2看来,总是建议从终结器而不是托管引用中释放非托管资源。

始终建议从 Dispose 方法释放非托管资源。 阅读这篇文章时,我仍然没有得到总要旨。

但是如果没有非托管资源,下面的模式应该可以工作。


根据 msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, msdn.microsoft.com/en-us/library/fs2xkftw.aspx 建议在终结器中释放本机资源,并使用 dispose( )。 如果显式调用 dispose(),它可以抑制终结器,即如果没有本机资源,我们就不需要终结器。

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool suppressFinalize) 
    {    
        if (!disposed)
        {
            //Just do the cleanup
            //and release resources
            disposed = true; 
        }
        if (!suppressFinalize)
        {
            GC.SuppressFinalize(this); 
        }
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);           
    } 
    ~MyClass() // the finalizer
    {     
        Dispose(false);    
    }
} 

因为您可能有对非托管资源(例如 Windows 句柄)的直接引用,并且即使没有人调用Dispose ,您也希望释放它们。

这是非常罕见的,但-通常你只有真的有非托管资源间接引用,通过其他托管类型,如果他们需要,这将有终结。

.Net 中的 Finalization + IDisposable实际上是两个不同的问题,它们试图用单一的一次性模式解决。

  • 托管资源清理
  • 非托管资源清理

非托管资源是不受 CLR 和垃圾收集器控制的项目。 像文件句柄、从 PInvoke 返回的内存等项目......如果这些资源没有被用户代码明确释放,它们将泄漏并在进程生命周期的剩余时间里存在。 他们被释放是至关重要的。

这就是终结器的用武之地。它会在对象被 CLR 收集之前在对象上运行。 这不需要消费者遵循一次性模式,因此是确保释放非托管资源以防止泄漏的良好后备。

如果您的代码不包含任何直接持有的非托管资源,则没有理由使用终结器。 拥有非托管资源的代码有责任拥有终结器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM