Сборка мусора объекта C # объявлена ​​в конструкторе - PullRequest
5 голосов
/ 31 августа 2011

В следующем коде я создаю DispatcherTimer в конструкторе класса. Никто не хранит ссылки на это.

В моем понимании таймер должен быть восстановлен сборщиком мусора через некоторое время после выхода из области видимости конструктора. Но этого не происходит! Даже после принудительного сбора мусора с 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 ]

4 голосов
/ 31 августа 2011

Таймеры довольно специфичны, так как они рутируют себя, вызывая

this.timerRoot = GCHandle.Alloc(this);

некоторые ссылки

РЕДАКТИРОВАТЬ:

Не осознавал, что это был DispatcherTimer - который не коренится непосредственно, но косвенно (до Dispatcher), что, в свою очередь, приводит к тому же эффекту ...

3 голосов
/ 31 августа 2011

Когда вы просто создаете a DispatcherTimer, ничто не мешает ему быть GCed. Однако вы устанавливаете IsEnabled = true, что вызовет Start() по таймеру. Когда это произойдет, будет выполнена эта строка кода:

this._dispatcher.AddTimer(this);

А теперь сам Dispatcher запускает таймер, что означает, что он не может быть GCed.

1 голос
/ 31 августа 2011

Он будет добавлен в очередь Dispatcher, которая будет укоренена.

...