Система. Таймеры. Таймер/Поточная обработка. Таймер по сравнению с Потоком с WhileLoop + Поток. Сон Для Периодических Задач

В моем приложении я должен отправить периодические импульсы в приложение "брата".

Это лучше выполненное с Системой. Таймеры. Таймер/Поточная обработка. Таймер или Используя Поток с некоторое время циклом и Потоком. Сон?

Интервал heartbeat составляет 1 секунду.

while(!exit)
{
   //do work
   Thread.Sleep(1000);
}

или

myTimer.Start( () => { 
                       //do work 
                      }, 1000); //pseudo code (not actual syntax)...
44
задан Alan 12 May 2010 в 20:16
поделиться

4 ответа

System.Threading.Timer имеет мой голос.

System.Timers.Timer предназначен для использования в серверной функциональности таймера (ваш код работает как сервер/сервис на хост-машине, а не запускается пользователем).

Поток с циклом While и командой Thread.Sleep - действительно плохая идея, учитывая наличие более надежных механизмов таймера в .NET.

32
ответ дан 26 November 2019 в 22:08
поделиться

Таймеры сервера отличаются от спящих потоков.

Во-первых, в зависимости от приоритета вашего потока и того, что еще выполняется, ваш спящий поток может быть разбужен, а может и нет, и запланирован его запуск с заданным вами интервалом. Если интервал достаточно велик и точность планирования не имеет большого значения, разумным выбором будет Thread.Sleep () .

Таймеры, с другой стороны, могут вызывать свои события в любом потоке, что позволяет улучшить возможности планирования. Стоимость использования таймеров, однако, немного усложняет ваш код - и тот факт, что вы не можете контролировать, какой поток запускает логику, на которой запускается событие таймера. Из документации:

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

Еще одно соображение заключается в том, что таймеры вызывают свой делегат Elapsed в потоке ThreadPool. В зависимости от того, насколько трудоемка и / или сложна ваша логика, вы можете не захотеть запускать ее в пуле потоков - вам может потребоваться выделенный поток. Другой фактор, связанный с таймерами, заключается в том, что если обработка занимает достаточно много времени, событие таймера может быть вызвано снова (одновременно) в другом потоке, что может быть проблемой, если выполняемый код не предназначен или не структурирован для параллелизма.

Не путайте Таймеры сервера с « Таймеры Windows ». Последнее обычно относится к сообщениям WM_TIMER, которые могут быть доставлены в окно, что позволяет приложению планировать и отвечать на синхронизированную обработку в своем основном потоке без сна. Однако таймеры Windows также могут ссылаться на Win API для низкоуровневой синхронизации (что не то же самое, что WM_TIMER).

23
ответ дан 26 November 2019 в 22:08
поделиться

Я обнаружил, что единственная реализация таймера, которая действительно масштабируется, - это System.Threading.Timer . Все остальные реализации кажутся довольно надуманными, если вы имеете дело с нетривиальным количеством запланированных элементов.

1
ответ дан 26 November 2019 в 22:08
поделиться

Ни то, ни другое :)

Сон обычно не одобряет (к сожалению, я не могу вспомнить подробности, но, во-первых, это неразрывный «блок»), и Таймеры идут с большим багажом. Если возможно, я бы рекомендовал System.Threading.AutoResetEvent как таковой

// initially set to a "non-signaled" state, ie will block
// if inspected
private readonly AutoResetEvent _isStopping = new AutoResetEvent (false);

public void Process()
{
    TimeSpan waitInterval = TimeSpan.FromMilliseconds (1000);

    // will block for 'waitInterval', unless another thread,
    // say a thread requesting termination, wakes you up. if
    // no one signals you, WaitOne returns false, otherwise
    // if someone signals WaitOne returns true
    for (; !_isStopping.WaitOne (waitInterval); )
    {
        // do your thang!
    }
}

Использование AutoResetEvent (или его двоюродного брата ManualResetEvent ) гарантирует истинный блок с потокобезопасностью сигнализация (для таких вещей, как изящное завершение, описанное выше). В худшем случае это лучшая альтернатива Sleep

Надеюсь, это поможет :)

21
ответ дан 26 November 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: