IDispospos GC.SuppressFinalize(this)位置
我为我的代码使用默认的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; } }
我想它是模板设计模式的一个明显案例。
您的抽象类旨在处理所需的所有重要/必要任务(此处为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
方法调用Dispose(true)
,并从终结器调用Dispose(false)
,作为尚未处理对象的回退。
调用SuppressFinalize
告诉GC,不需要调用对象的终结器,大概是因为调用Dispose
时所有的清理工作都已完成。
如果你的class级没有终结器,那么你根本不需要调用SuppressFinalize
,因为没有终结器可以抑制!
Joe Duffy 在处理,定型,垃圾收集等方面有一些很好的指导 。
我认为任何一种布局都可以选择,但可能他们想强调“在此方法中放置所有释放代码”在受保护的Dispose方法中,因此他们将其他工件处理(抑制终结)放在别处。
另外,假设一个派生类有另一个原因来调用受保护的Dispose方法,但仍然希望最终化发生(出于任何想象的原因,我不知道)。
原因.Dispose是当托管代码(您的代码)处置对象从而选择退出完成时。 人们通常会通过终结者创建另一条进入Dispose(bool处理)的路线,并且该调用对于终结者来说没有任何意义。
这个想法是你的清理代码应该只被调用一次。 但是有两个入口点: Dispose
方法和对象终结器。 调用Dispose
,您选择退出finalization,以便只调用一次清理代码。 这里的代码可能会更好地说明它。
引用:
// NOTE: Leave out the finalizer altogether if this class doesn't // own unmanaged resources itself, but leave the other methods // exactly as they are.