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