Когда SystemTimers.Timer считается мусором, если ссылка не сохранена? - PullRequest
0 голосов
/ 28 февраля 2020

Мне очень любопытно узнать, когда System.Timers.Timer считается мусором и для этого собирается сборщиком мусора, если я не храню ссылку на него, но он включен.
Но в какой момент мой таймер считается мусором?

Рассмотрим следующий код:

public void TriggerUpdateStatus() {
    toolStripStatusLabel1.Text = "*";
    new Timer() {
        Interval = 1000,
        Enabled = true
    }.Elapsed += new ElapsedEventHandler(
        (object sender, ElapsedEventArgs args) => {
            toolStripStatusLabel1.Text = "";
            Timer t = ((System.Timers.Timer) sender);
            t.Stop();
            t.Dispose();//Is this needed?
        });
}

Этот блок кода будет запускаться раз в две секунды, когда мой код вызывает обновление, Затем он добавляет символ звезды в нижнем углу моей формы, указывая, что связь жива и здорова. Я создаю Таймер без ссылки, который просто через секунду снова удалит звезду, остановит ее и избавится от нее.

1 Ответ

0 голосов
/ 28 февраля 2020

Нет, t.Dispose(), не обязательно, оно будет собрано независимо.

Сам вопрос, кажется, выражает глубокое недопонимание о том, как работают G C и Dispose (подчеркиваю слово кажется ). G C абсолютно не знает, что делает Dispose, и ему наплевать. То, что объект расположен или нет, не играет, чтобы понять, является ли этот конкретный объект элегантным для сбора; это две совершенно ортогональные концепции.

Утилизация - это механизм освобождения неуправляемых ресурсов, он не имеет ничего общего с работой сборщика мусора.

Если это понятно, то Dispose хотя вежливо, даже не обязательно; Dispose (или необходимая его часть) будет работать в любом случае, когда таймер будет в конечном итоге собран (объект недостижим и недолговечен, поэтому не должен занимать слишком много времени), помещается в очередь финализаторов и завершается в неустановленном будущем; это вежливо и рекомендуется использовать для детерминированного освобождения всех неуправляемых ресурсов, связанных с объектом, вместо того, чтобы полагаться на них всякий раз, когда очередь финализатора решает запустить, что поднимает следующий пункт:

Почему вы обновляете Timer каждые две секунды, а затем немедленно его утилизировать? Не было бы намного проще иметь один таймер и каждый раз сбрасывать его?

...