Что лучше для службы Windows: ожидание или таймер?

StackOverflow https://stackoverflow.com/questions/1099516

  •  11-09-2019
  •  | 
  •  

Вопрос

Этот вопрос о таймерах для служб Windows заставил меня задуматься:

Скажем, у меня есть (и есть) служба Windows, ожидающая WaitHandle и когда его просыпают, он погружается в ожидание, как я показал ниже на блок-схеме.

диаграмма ожидания вращения http://www.86th.org/waitspin.jpg

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

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

Дайте мне знать, если это должна быть вики

Это было полезно?

Решение

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

На самом деле я бы не сказал, что вы выполняете ожидание вращения, поскольку я обычно думаю о ожидании вращения как о чем-то, что не спит.Он просто сжигает все время процессора в ожидании сигнала начала работы.

Другие советы

Спящий поток и ожидание дескриптора с тайм-аутом — это, по сути, одно и то же.Я предполагаю, что таймеры по сути реализованы с использованием сна, так что особой разницы здесь тоже нет.Другими словами, вы можете упростить свой код, ожидая дескриптора с тайм-аутом в одном цикле и проверяя, почему ожидание было освобождено (доступность данных или тайм-аут), вместо реализации отдельных циклов ожидания и ожидания.Немного более эффективен, чем независимые циклы.

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

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

Мы используем нити.Они не только работают как таймер, но и дают нам возможность выполнять другие операции, пока поток спит.

Я думаю, что это действительно зависит от ваших требований:

  1. Запустить задачу каждый 5 минут (например, 12:00, 12:05, 12:10, ...)
  2. После завершения текущей задачи запустите следующую задачу после 5 мин.

Timer кажется простым для случая 1, а Thread.Sleep — для случая 2, хотя Timer и Thread.Sleep могут выполнять и то, и другое.

На самом деле я оставил более длинный комментарий (включая некоторые соображения по случаю 1) по аналогичному вопросу (Запланированное выполнение службы Windows).

Опросы – это плохо, и их почти всегда можно избежать.Иногда для тривиальных вещей это менее плохо, чем сложность, необходимая для того, чтобы их избежать.

Какого источника вы опровергаете "есть данные?" Что вы не можете превратиться в какую -то ручку, ожидая?

Кроме того, не Sleep() в серьезном коде (например, в сервисе) в течение значительного периода времени.Единственное, что вы можете заблокировать, это WaitFor[Single|Multiple]Objects(...) где список дескрипторов включает событие, которое запускается, когда приходит время завершить процесс.Находите везде, куда вы звоните Sleep(millisec) и замените его на WaitForSingleObjects(g_shutdownEvent, millisec).

Как объясняет Рэймонд Чен: "Да что угодно." Если вы не можете найти способ получить уведомлен когда ваши данные будут готовы - тогда и ваш SOL.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top