Сборщик мусора убьет объект класса где таймер отрабатывает одно условие?

230
09 декабря 2016, 08:50

Сборщик мусора убьет объект класса где таймер отрабатывает одно условие? Я хочу что бы условие отрабатывалось раз в сутки, что-то нужно добавить в метод\класс?

    Starter startSomeMethod;
    private int _hour { get; set; }
    private int _minute { get; set; }
    private Timer _timer;
    private object _lockThis;
    public  Updater(Starter start, int hour, int minutes)
    {
        _hour = hour;
        _minute = minutes;
        startSomeMethod = start;
        if (_lockThis != null)
            return;
        _lockThis = new object();
        _timer = new Timer(new TimerCallback(OnTimedEvent), null, 0, 45000);
    }
    private void OnTimedEvent(object obj)
    {
        lock (_lockThis)
        {
            DateTime dd = DateTime.Now;
            if (dd.Hour == _hour && dd.Minute == _minute)
            {
              startSomeMethod();   
            }
        }
    }
Answer 1

Если ваш класс, который содержит _timer, не умрёт, то он будет содержать ссылку, которая будет держать ваш таймер «на плаву».

Поэтому вам нужно позаботиться о том, чтобы объект, содержащий ссылку, не умер.

MSDN подчёркивает (привожу английский текст, т. к. русский перевод в MSDN неточен):

As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.

то есть

Вы обязаны держать живую ссылку на таймер пока вы используете его. Как и любой управляемый объект, таймер, на которого не останется ссылок, может быть убран сборщиком мусора. То, что таймер всё ещё активен, не предотвращает сборку его сборщиком мусора.

Если заглянуть в исходник текущей имплементации таймера, можно увидеть, что в случае, когда вы конструируете таймер с одним лишь callback'ом, в глобальную очередь уходит ссылка на сам таймер. А значит, таймер в этом случае будет держать себя в памяти сам. Но это поведение не гарантировано документацией, и в предыдущих версиях .NET таймер вёл себя по-другому. И скорее всего в будущем тоже. Поэтому полагаться на это просто опасно, полагайтесь лучше на документацию.

Ну и кроме того, вы используете другой конструктор.

READ ALSO
Преобразование string в DateTime (List)

Преобразование string в DateTime (List)

Здравствуйте! Возникла проблема при изменении формата переменнойУ меня есть класс:

730
Извлечь несколько значений из Combobox

Извлечь несколько значений из Combobox

Есть коллекция, в которой каждому элементe соответствует 4 значения(один из них, это имя, которое отображается свойством DisplayMember в комбобоксе...

292
Хорошая архитектура ASP.NET

Хорошая архитектура ASP.NET

ЗдравствуйтеЯ пытаюсь разобраться в том, как правильнее составлять архитектуру ASP

326
Как заполнить ComboBox из массива?

Как заполнить ComboBox из массива?

У меня есть большой стринговый массив и нужно по нему заполнить ComboBox в ListBox можно сделать так listBoxItems

321