[英]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.