2010-05-07 59 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,因爲終結器不能保證以任何順序運行。

在這種情況下,它只是儘可能好地關閉事情。如果手柄還沒有最終確定,冷卻,讓我們處理它,否則,終結者會盡力。

相關問題