2010-03-24 41 views
0
public class ABC 
{ 
    public ABC(IEventableInstance dependency) 
    { 
     dependency.ANewEvent += MyEventHandler; 
    } 

    private void MyEventHandler(object sender, EventArgs e) 
    { 
     //Do Stuff 
    } 
} 

讓我們說ABC的一個實例是一個長活體對象,並且我的依賴項是一個更長的運行對象。當ABC的實例需要清理時,我有兩個選項。處置生活依賴性很大的對象

我可以有一個Cleanup()方法來取消訂閱ANewEvent事件,或者我可以實現IDisposable並在Dispose中取消接口事件。現在我無法控制消費者是否會調用dispose方法,或者我應該使用Cleanup方法。

我應該實施終結者並退訂嗎?它感覺骯髒,但我不希望懸掛ABC的例子。

想法?

回答

1

這個問題的顯而易見的解決方案是,在離開這個問題一年之後,我應該實現IDisposable並簡單地取消訂閱我的Dispose()中的事件。

由於我對依賴關係的生命週期沒有責任,因此我無法對它做任何事情。

1

我讀到這對MSDN

因爲Dispose方法必須 顯式調用,對象是 實現IDisposable 還必須 實現一個終結處理 釋放資源時,處置不 叫 。默認情況下,垃圾收集器會在回收其內存之前自動調用對象的終結器( )。但是,一旦調用了Dispose 方法,通常不需要垃圾 收集器調用已處理的對象的終結器的 。爲了防止 自動完成,Dispose 實現可以調用 GC.SuppressFinalize方法。

因此,在這種情況下,爲了安全起見,我會實現IDisposable和終結器。我同意,這有點髒,但是再次,這是您在處理長壽命物體時付出的代價。

+1

但是,僅當我們使用非託管代碼時才需要終結器。 – 2011-02-16 10:16:17

+0

@RayBooysen:問題不在於是否使用非託管代碼,而在於是否正在使用需要清理的內容,哪些內容可以在終結器的上下文中進行有效清理。在託管代碼中有完整的上下文對於清理是必需的,但也有很多地方,即使未調用Dispose會導致問題,終結器也無法幫助解決(例如,因爲沒有線程安全的清理方法,或者因爲需要清理來分離會阻止終結器運行的強引用)。 – supercat 2012-10-23 18:30:12