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

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

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

http://www.86th.org/waitspin.jpg

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

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

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

6 ответов

Решение

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

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

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

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

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

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

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

Какой источник вы опрашиваете "Есть данные?" что ты не можешь превратиться в какое-то ручное ожидание?

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

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

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

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

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

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

Другие вопросы по тегам