2011-04-22 31 views
2

比方說,我動態創建一個像這樣的計時器:當該參考超出範圍動態System.Timers.Timer和垃圾收集?

 System.Timers.Timer expirationTimer = new Timer(expiration * 60000); 
     expirationTimer.Elapsed += (sender, e) => removeExpiredCacheEntry(sessionID); 
     expirationTimer.Start(); 

,將Timer對象被垃圾收集?如果是這樣,事件還會發生嗎?如果不是,那麼在這種情況下我將如何避免內存泄漏?

謝謝!

回答

2

this answer,定時對象確實將符合垃圾回收,並停止在某一時刻觸發事件。

但是,垃圾收集是反其道而行之。如果我們有

publisher.SomeEvent += target.SomeHandler; 

然後「出版商」將讓「目標」活着,但是「目標」不會保持「發行人」活着。

+0

謝謝。很高興在這方面有具體的答案。 – 2012-01-03 18:08:24

2

一旦對象超出範圍,並且沒有其他引用。它最終會被垃圾收集。但這可能不會發生一段時間。所以,定時器可能會持續發射,直到它被事實上的垃圾收集。

這只是一個猜測,不過,因爲我沒有在時刻,以測試它的能力。

UPDATE:

我只是寫了一個小的測試程序,看起來是這樣的:

static void Main(string[] args) 
{ 
    SetTimer(); 
    Console.ReadLine(); 
} 

private static void SetTimer() 
{ 
    Timer expirationTimer = new Timer(1000); 
    expirationTimer.Elapsed += (sender, e) => Notify(e); 
    expirationTimer.Start(); 
} 

private static void Notify(ElapsedEventArgs e) 
{ 
    Console.WriteLine(string.Format("Notified! {0}", e.SignalTime)); 
} 

的計時器保持射擊很長一段時間(我最終剛剛結束的程序)。有趣的是,我在主函數中插入了15秒的睡眠時間,然後調用GC.Collect()並且即使在強制垃圾收集之後定時器仍保持運行,儘管無法保證調用GC.Collect()實際上會執行任何操作。

我也嘗試在using語句包裹的計時器,並正確地關閉計時器立即(沒有打印任何內容到屏幕)。所以,我相信我的假設是正確的,垃圾收集最終會收集定時器並處理它。但是沒有辦法確定這將是什麼時候。

+0

謝謝!我最終只是將計時器本身傳遞給事件處理程序,該處理程序應該避免垃圾收集,並讓我直接調用Dispose()。 – 2011-04-22 23:04:31