IDisposable GC.SuppressFinalize(this)位置
-
03-07-2019 - |
题
我为我的代码使用默认的IDisposable实现模板(模式)。
片段:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
}
//cleanup unmanaged resources
this.disposed = true;
}
}
我的问题:为什么呼叫“GC.SuppressFinalize(this)”在Dispose公共方法?我会放置“GC.SuppressFinalize(this)”。在“if(isDisposing)”中处理受管资源后受保护方法的一部分。
像这样:
protected virtual void Dispose(bool isDisposing)
{
if (!this.disposed)
{
if (isDisposing)
{
//cleanup managed resources
GC.SuppressFinalize(this);
}
//cleanup unmanaged resources
this.disposed = true;
}
}
解决方案
我认为它是模板设计模式的明显案例。
您的抽象类旨在处理所需的所有重要/必要任务(此处为GC.SuppressFinalize(this)),并允许派生类仅覆盖代码的某些部分。
这里有2个案例:
在Dispose中,Snippet 1,SuppressFinalize
Snippet 2,SuppressFinalize,Dispose(true)
这里,Snippet 1确保始终执行GC.SuppressFinalize。在代码片段2中,GC.SuppressFinalize的执行受派生类的支配。
因此,通过在Dispose方法中放置GC.SuppressFinalize,您作为类的设计者将始终确保无论派生类编写的代码是什么,都将执行GC.SuppressFinalize。
这只是在Dispose中编写SuppressFinalize而不是Dispose(true)的好处。
其他提示
Dispose(bool isDisposing)
方法不属于 IDisposable
界面。
您通常会从 Dispose(true) =“noreferrer”> Dispose
方法,并从终结器中调用 Dispose(false)
,作为对象尚未被删除的情况下的后备地布置。
致电 SuppressFinalize
告诉GC,不需要调用对象的终结器,大概是因为在调用 Dispose
时完成了所有清理工作。
如果您的班级没有终结器,那么您根本不需要调用 SuppressFinalize
,因为没有终结器可以抑制!
Joe Duffy有一些很棒的处理,定稿,垃圾收集等指南。
我认为可以选择任一种布局,但可能他们想强调“将所有解除分配代码放入此方法中”。在受保护的Dispose方法中,所以他们将其他工件(抑制终结)放在别处。
另外,假设一个派生类有另一个原因来调用受保护的Dispose方法,但是仍然希望完成最终化(出于任何想象的原因,我不知道)。
原因.Dispose是当托管代码(您的代码)处置对象从而选择退出完成时。人们通常会通过终结者创建另一条进入Dispose(bool处理)的路线,并且该调用对于终结者来说没有任何意义。
这个想法是你的清理代码只应该被调用一次。但是有两个入口点: Dispose
方法和对象终结器。当调用 Dispose
时,您选择退出最终化,以便只调用一次清理代码。 此处的代码可能会更好地说明这一点。
引用:
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources itself, but leave the other methods
// exactly as they are.