2011-08-31 30 views
5

在下面的代碼中,我在類的構造函數中創建了一個DispatcherTimer。沒有人保留它的參考。在構造函數中聲明的C#對象的垃圾回收

在我的理解中,計時器應該在離開構造函數的作用域後的一段時間被垃圾回收器回收。 但這並沒有發生!即使在強制垃圾回收之後,GC.Collect()

發生了什麼事情?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     new DispatcherTimer 
     { 
      Interval = TimeSpan.FromMilliseconds(100), 
      IsEnabled = true 
     } 
     .Tick += (s, e) => 
     { 
      textBlock1.Text = DateTime.Now.ToString(); 
     }; 
    } 
} 

回答

3

當你只是構建一個DispatcherTimer,沒有什麼阻止它被GCed。但是,您設置了IsEnabled = true,這將在計時器上調用Start()。如果是,情況發生,這行代碼會被執行:

this._dispatcher.AddTimer(this); 

而且現在Dispatcher本身生根定時器,這意味着它不能GCed。

4

定時器比較特殊,因爲他們根自己通過調用

this.timerRoot = GCHandle.Alloc(this); 

一些鏈接

編輯:

沒有意識到這是一個DispatcherTimer - 不直接,但間接的(到Dispatcher),這反過來又導致同樣的效果深深紮根......

+0

這實際上是錯誤的......它是一種不同類型的計時器。 – dlev

+0

DispatcherTimers是否遵循與Threading.Timers相同的垃圾收集規則?如果是這樣,沒有對定時器的字段引用(只有本地引用)會導致垃圾回收本身...但我認爲DispatcherTimers不是這種情況... – Jeff

+0

@ JeffN825所有對象都受到相同的GC規則:如果您無法從GC根目錄訪問,則您有資格使用GC。在這種情況下,該代碼甚至不是來自正確的計時器類。 – dlev

1

它將被添加到Dispatcher隊列中,該隊列將被生根。