Что лучше для службы Windows: ожидание или таймер?
-
11-09-2019 - |
Вопрос
Этот вопрос о таймерах для служб Windows заставил меня задуматься:
Скажем, у меня есть (и есть) служба Windows, ожидающая WaitHandle и когда его просыпают, он погружается в ожидание, как я показал ниже на блок-схеме.
диаграмма ожидания вращения http://www.86th.org/waitspin.jpg
Мне любопытно, будет ли использование таймера лучше, чем цикл ожидания-отжима (иногда называемый ожиданием вращения).Честно говоря, я никогда не использовал таймеры ни для чего, кроме как для собственных нужд.
У меня нет никаких планов по переходу, если только различия не будут глубокими, а преимущества использования таймера не поражают.Тем не менее, меня очень интересуют мысли людей по поводу будущего развития этого проекта.
Дайте мне знать, если это должна быть вики
Решение
Я не вижу никакой пользы от таймера.По сути, вы в любом случае ведете себя как таймер во время вызова сна, и вы не потребляете пропускную способность, поскольку сон уступает временной интервал.Наличие явного таймера пробуждения и звонка только усложнит код.
На самом деле я бы не сказал, что вы выполняете ожидание вращения, поскольку я обычно думаю о ожидании вращения как о чем-то, что не спит.Он просто сжигает все время процессора в ожидании сигнала начала работы.
Другие советы
Спящий поток и ожидание дескриптора с тайм-аутом — это, по сути, одно и то же.Я предполагаю, что таймеры по сути реализованы с использованием сна, так что особой разницы здесь тоже нет.Другими словами, вы можете упростить свой код, ожидая дескриптора с тайм-аутом в одном цикле и проверяя, почему ожидание было освобождено (доступность данных или тайм-аут), вместо реализации отдельных циклов ожидания и ожидания.Немного более эффективен, чем независимые циклы.
В идеале вы бы вообще не использовали режим сна и просто полагались бы на то, что код генерации данных правильно вызовет событие, которого ожидает ваш код потребления, с длительным тайм-аутом для обработки, когда источник события исчезнет.
Если данные являются внешними, например, в сокете или другом устройстве ввода, то дескриптор обычно можно установить, чтобы разрешить ожидание доступности данных - в этом случае нет необходимости опрашивать, поскольку о событии всегда будет сигнализироваться, когда данные будут готовы. для потребления.
Мы используем нити.Они не только работают как таймер, но и дают нам возможность выполнять другие операции, пока поток спит.
Я думаю, что это действительно зависит от ваших требований:
- Запустить задачу каждый 5 минут (например, 12:00, 12:05, 12:10, ...)
- После завершения текущей задачи запустите следующую задачу после 5 мин.
Timer кажется простым для случая 1, а Thread.Sleep — для случая 2, хотя Timer и Thread.Sleep могут выполнять и то, и другое.
На самом деле я оставил более длинный комментарий (включая некоторые соображения по случаю 1) по аналогичному вопросу (Запланированное выполнение службы Windows).
Опросы – это плохо, и их почти всегда можно избежать.Иногда для тривиальных вещей это менее плохо, чем сложность, необходимая для того, чтобы их избежать.
Какого источника вы опровергаете "есть данные?" Что вы не можете превратиться в какую -то ручку, ожидая?
Кроме того, не Sleep()
в серьезном коде (например, в сервисе) в течение значительного периода времени.Единственное, что вы можете заблокировать, это WaitFor[Single|Multiple]Objects(...)
где список дескрипторов включает событие, которое запускается, когда приходит время завершить процесс.Находите везде, куда вы звоните Sleep(millisec)
и замените его на WaitForSingleObjects(g_shutdownEvent, millisec)
.
Как объясняет Рэймонд Чен: "Да что угодно." Если вы не можете найти способ получить уведомлен когда ваши данные будут готовы - тогда и ваш SOL.