Таймеры c # естественно многопоточные? - PullRequest
3 голосов
/ 14 июня 2011

Если у меня два системных таймера, запускающих события в 10 и 20 секунд соответственно, являются ли вызовы функций событий многопоточными?В приведенном ниже сценарии у меня есть таймеры, которые запускают события с интервалами 10 и 12 соответственно.Ожидается, что функция My10sEvent будет вызвана первой.Если это медленная функция, выполнение которой занимает 8 секунд, заблокирует ли оно другое событие (tmr12s) или второе событие сработает по времени через 12 с?

System.Timers.Timer tmr10s = new System.Timers.Timer(10000.0);
tmr10s.Enabled = true;
tmr10s.Elapsed += new ElapsedEventHandler(My10sEvent);

System.Timers.Timer tmr12s = new System.Timers.Timer(12000.0);
tmr12s.Enabled = true;
tmr12s.Elapsed += new ElapsedEventHandler(My12sEvent);

Thread.Sleep(System.Threading.Timeout.Infinite); //sleep indefinitely to let the above events fire

Ответы [ 3 ]

4 голосов
/ 14 июня 2011

CLR использует выделенный поток для отслеживания активных таймеров System.Timers.Timer и System.Threading.Timer.Событие Elapsed возникает в другом потоке, извлеченном из пула потоков.

Так что да, они продолжают работать, не влияя друг на друга.Вы должны быть очень осторожны, вполне возможно, что ваш обработчик событий Elapsed будет вызван снова, пока он еще выполняется.Что происходит, когда это занимает больше времени, чем интервал.Или хуже, когда машина сильно загружена или у вас много активных потоков пула потоков.Это может очень трудно диагностировать сбой, если ваш обработчик событий не является поточно-ориентированным.Это почти никогда не бывает.Установка для свойства таймера AutoReset значения false - простой способ избежать этой проблемы.

3 голосов
/ 14 июня 2011

Похоже, что он не заблокируется, если вы используете System.Threading.Timer или вызываете System.Timers.Timer без объекта SynchronizingObject.

Аналогичный вопрос: Происходят ли таймеры C # в отдельном потоке?

1 голос
/ 14 июня 2011

Из документации System.Timers.Timer:

Серверный таймер предназначен для использования с рабочими потоками в многопоточной среде.Таймеры сервера могут перемещаться между потоками для обработки инициированного события Elapsed, что приводит к большей точности, чем таймеры Windows, для своевременного инициирования события.

Так что да, это так.

Далее, из документации по свойствам System.Timers.Timer.SynchronizingObject:

Когда SynchronizingObject равен null, метод, который обрабатываетИстекшее событие вызывается в потоке из пула системных потоков.Для получения дополнительной информации о пулах системных потоков см. ThreadPool.

Таким образом, события возникают в потоках пула потоков, если не задан SynchronizingObject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...