2010-05-07 27 views
3

我曾经很确定答案是“否”,如Overriding the Finalize methodObject.Finalize documentation中所解释的那样。是否允许终结器调用其他托管类的方法?

然而,尽管随机通过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实际上有两种私有方法,InternalDisposeInternalFinalize,在这种情况下将调用InternalDispose。这不是问题吗?为什么不呢?...

回答

2

是的,终结器被允许调用其他方法。地狱,你甚至可以做一些有趣的事情,比如重新注册类型来完成定制。但是在处理可终结实例时你必须显式检查null,因为终结器不能保证以任何顺序运行。

在这种情况下,它只是尽可能好地关闭事情。如果手柄还没有最终确定,冷却,让我们处理它,否则,终结者会尽力。

相关问题