Использование объекта Timer в параметре
От: _NN_  
Дата: 25.11.15 21:39
Оценка:
Много раз замечал такой код:

using System.Threading;

var t = new Timer(() => {
  t.Dispose();
}, ...);


Насколько правомерно такое использование ?
Не может ли быть ситуации когда t.Dispose вызовется до присваивания ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Использование объекта Timer в параметре
От: nikov США http://www.linkedin.com/in/nikov
Дата: 25.11.15 22:20
Оценка: +2
Здравствуйте, _NN_, Вы писали:

_NN>Много раз замечал такой код:


_NN>
_NN>using System.Threading;

_NN>var t = new Timer(() => {
_NN>  t.Dispose();
_NN>}, ...);
_NN>


_NN>Не может ли быть ситуации когда t.Dispose вызовется до присваивания ?


Может. Именно поэтому компилятор скажет "Use of unassigned local variable 't'" на t.Dispose().
Re: Использование объекта Timer в параметре
От: Sinix  
Дата: 26.11.15 05:57
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Не может ли быть ситуации когда t.Dispose вызовется до присваивания ?

Nikov ответил выше, дополню.

При некоторых условиях GC может пожрать таймер ещё до вызова каллбэков. Например, если переменная t нигде не используется и задан непустой dueTime.
Тут ещё есть оччень милый недокументированный нюанс из разряда "знать бы раньше": таймер использует объект state, переданный в конструктор в качестве gc root. Т.е. пока state жив, таймер будет работать, пока его не остановят вручную.
Пруф, ещё один. Тёмное наследие первого фреймворка, даа.

С System.Timers.Timer тоже не всё очевидно. Смотрим последний абзац по первой из ссылок выше.

Summary (полувсерьёз): используйте Task.Delay()
Re[2]: Использование объекта Timer в параметре
От: _NN_  
Дата: 26.11.15 10:42
Оценка:
Здравствуйте, nikov, Вы писали:

Пардон.
Имелось ввиду конечно:


using System.Threading;

Timer t = null;
t = new Timer(() => {
  t.Dispose();
}, ...);
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.