Использование Thread.Sleep () в службе Windows - PullRequest
14 голосов
/ 16 июня 2009

Я пишу службу Windows, которая должна спать в течение длительного времени (15 часов - самый длинный, а 30 минут - самый короткий). В настоящее время я использую Thread.Sleep (рассчитанное время) , чтобы перевести мой код в спящий режим. Является ли Thread.Sleep лучшим вариантом или я должен использовать таймер? Я гуглял это некоторое время и не могу найти краткий ответ. Поскольку это служба Windows, мне не нужно беспокоиться о блокировке интерфейса, поэтому я не могу придумать причину не использовать Thread.Sleep.

Любое понимание будет оценено.

Ответы [ 5 ]

20 голосов
/ 16 июня 2009

Я бы использовал таймер Thread.Sleep, который мог бы вызвать блокировку, которая могла бы помешать завершению работы службы.

Если интервал такой широкий и регулярный, вы можете просто запланировать его. Но если вы говорите о длинных, непоследовательных интервалах, то да, таймер был бы лучше.

10 голосов
/ 16 июня 2009

Поскольку диспетчер управления службами может попросить остановить службу в любое время, ваш поток всегда должен быть готов ответить на эти запросы, поэтому вы не должны использовать Thread.Sleep (). Вместо этого создайте событие ручного сброса в главном потоке и используйте его метод WaitOne с таймаутом в вашем рабочем потоке. WaitOne вернет false по истечении времени.

Когда вызываются методы класса обслуживания OnStop или OnShutdown, установите событие, и это заставит WaitOne вернуть значение true, после чего вы сможете выйти из рабочего потока.

7 голосов
/ 16 июня 2009

Обычно считается плохой практикой использовать Thread.Sleep() во многих случаях.

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

Если службу нужно запускать только через запланированные промежутки времени, я рекомендую вам использовать планировщик задач Windows, чтобы Windows могла запускать приложение, когда это необходимо.

6 голосов
/ 16 июня 2009

Не стоит заранее рассчитывать такое большое количество времени и спать часами. В лучшем случае спите минуту, затем просыпайтесь и пересчитывайте время, снова спите не более минуты. Я предполагаю, что вычисление очень дешево или его можно сделать очень дешево с помощью кэширования. Проблема, которую я советую устранить, заключается в том, что часы компьютера удивительно «скачут», в основном из-за смещения времени, исправленного службой сетевого времени, также из-за экономии летнего времени и не в последнюю очередь из-за того, что пользователь настраивает часы. Поэтому лучше постоянно пересчитывать время для таких длинных интервалов, даже если это означает просыпаться каждую минуту или около того. И не удивляйтесь (т. Е. Не утверждайте), если вы проснетесь в «прошлом», часы могут вернуться во времени.

1 голос
/ 16 июня 2009

Еще одна вещь, которую следует учитывать, это то, что потоки являются конечными ресурсами, и каждый поток потребляет часть памяти (1 МБ?) Для своего стека. Они также могут увеличить нагрузку на планировщик.

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

...