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