В моем приложении я должен отправить периодические импульсы в приложение "брата".
Это лучше выполненное с Системой. Таймеры. Таймер/Поточная обработка. Таймер или Используя Поток с некоторое время циклом и Потоком. Сон?
Интервал heartbeat составляет 1 секунду.
while(!exit)
{
//do work
Thread.Sleep(1000);
}
или
myTimer.Start( () => {
//do work
}, 1000); //pseudo code (not actual syntax)...
System.Threading.Timer имеет мой голос.
System.Timers.Timer предназначен для использования в серверной функциональности таймера (ваш код работает как сервер/сервис на хост-машине, а не запускается пользователем).
Поток с циклом While и командой Thread.Sleep - действительно плохая идея, учитывая наличие более надежных механизмов таймера в .NET.
Таймеры сервера отличаются от спящих потоков.
Во-первых, в зависимости от приоритета вашего потока и того, что еще выполняется, ваш спящий поток может быть разбужен, а может и нет, и запланирован его запуск с заданным вами интервалом. Если интервал достаточно велик и точность планирования не имеет большого значения, разумным выбором будет Thread.Sleep ()
.
Таймеры, с другой стороны, могут вызывать свои события в любом потоке, что позволяет улучшить возможности планирования. Стоимость использования таймеров, однако, немного усложняет ваш код - и тот факт, что вы не можете контролировать, какой поток запускает логику, на которой запускается событие таймера. Из документации:
Серверный таймер разработан для использования с рабочими потоками в многопоточной среде. Серверные таймеры могут перемещаться между потоками для обработки возникшего события Elapsed, что приводит к большей точности, чем таймеры Windows при возникновении события на время.
Еще одно соображение заключается в том, что таймеры вызывают свой делегат Elapsed в потоке ThreadPool. В зависимости от того, насколько трудоемка и / или сложна ваша логика, вы можете не захотеть запускать ее в пуле потоков - вам может потребоваться выделенный поток. Другой фактор, связанный с таймерами, заключается в том, что если обработка занимает достаточно много времени, событие таймера может быть вызвано снова (одновременно) в другом потоке, что может быть проблемой, если выполняемый код не предназначен или не структурирован для параллелизма.
Не путайте Таймеры сервера с « Таймеры Windows ». Последнее обычно относится к сообщениям WM_TIMER, которые могут быть доставлены в окно, что позволяет приложению планировать и отвечать на синхронизированную обработку в своем основном потоке без сна. Однако таймеры Windows также могут ссылаться на Win API для низкоуровневой синхронизации (что не то же самое, что WM_TIMER).
Я обнаружил, что единственная реализация таймера, которая действительно масштабируется, - это System.Threading.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
Надеюсь, это поможет :)