正如 Overriding the Finalize 方法和Object.Finalize 文档中所解释的那样,我曾经很确定答案是否定的。
但是,在 Reflector 中随机浏览FileStream
时,我发现它实际上可以从终结器中调用这样的方法:
private SafeFileHandle _handle;
~FileStream()
{
if (this._handle != null)
{
this.Dispose(false);
}
}
protected override void Dispose(bool disposing)
{
try
{
...
}
finally
{
if ((this._handle != null) && !this._handle.IsClosed) // <=== HERE
{
this._handle.Dispose(); // <=== AND HERE
}
[...]
}
}
我开始想知道由于其编写方式的确切原因,这是否总是有效,因此“不要接触终结器中的托管类”是否只是一个指南,只要有充分的理由和必要的知识就可以打破它对。
我挖得更深一点,发现当“规则”被打破时可能发生的最坏情况是正在访问的托管对象已经完成,或者可能在单独的线程上并行完成。因此,如果 SafeFileHandle 的终结器没有做任何会导致后续调用 Dispose 失败的事情,那么上面应该没问题......对吗?
问题:那么毕竟可能存在这样的情况,即可以从终结器可靠地调用另一个托管类上的方法?我一直认为这是错误的,但这段代码表明这是可能的,并且有足够好的理由这样做。
奖励:观察到,SafeFileHandle
甚至不会知道它是从终结器调用的,因为这只是对Dispose()
. 基类 ,SafeHandle
实际上有两个私有方法,InternalDispose
和InternalFinalize
, 在这种情况下InternalDispose
会被调用。这不是问题吗?为什么不?...