Подтвердить что ты не робот

System.Timers.Timer/Threading.Timer vs Thread with WhileLoop + Thread.Sleep для периодических задач

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

Улучшено ли это с помощью System.Timers.Timer/Threading.Timer или с помощью Thread с циклом while и Thread.Sleep?

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

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

или

myTimer.Start( () => { 
                       //do work 
                      }, 1000); //pseudo code (not actual syntax)...
4b9b3361

Ответ 1

System.Threading.Timer имеет мое голосование.

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

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

Ответ 2

Серверные таймеры - это другое существо, чем спящие потоки.

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

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

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

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

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

Ответ 3

Ни:)

Сон обычно нахмурился (к сожалению, я не помню подробностей, но во-первых, это неперехваченный "блок" ), а Timer поставляется с большим количеством багажа. Если возможно, я рекомендовал бы 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

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

Ответ 4

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