Может ли кто-нибудь указать мне самый простой способ установить таймер в службе Win32?
Я полагаю, я мог бы создать для этой цели фиктивное окно или сделать так, чтобы второй поток подсчитывал тики, но что лучше? Есть способ более элегантный?
Заранее спасибо.





Вы можете использовать SetTimer для установки таймера, а затем перехватить сообщение WM_TIMER в своем цикле сообщений.
Пример:
// Устанавливаем таймер на истечение 10 секунд
SetTimer (hwnd, IDT_TIMER1, 10000, (TIMERPROC) NULL);
... затем в цикле сообщений:
переключатель (wParam)
{
case IDT_TIMER1:
// Boom goes the dynamite
Вы также можете объявить функцию типа TIMERPROC и вызвать ее по истечении таймера, если вы не хотите выполнять обработку цикла сообщений.
Спасибо - в моем сервисе нет цикла сообщений, чтобы поймать сообщение :)
Так что создайте его! Очередь сообщений устанавливается операционной системой после вызова :: GetMessage или :: PeekMessage.
Вы можете отправлять сообщения WM_TIMER своему основному потоку. Параметр lParam для сообщения - это адрес функции обратного вызова, или вы можете оставить его NULL и обработать его самостоятельно в насосе сообщений.
В этом примере мы отправляем таймер в насос сообщений потока, нет необходимости иметь окно, связанное с таймером.
UINT timer;
VOID CALLBACK Timer(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
KillTimer(0, timer);
}
timer=SetTimer(0, // window handle
0, // id of the timer message, leave 0 in this case
10000, // millis
Timer // callback
);
// pump messages
while (GetMessage) etc...
Обратный вызов таймера будет вызван DispatchMessage. Этот вопрос напомнил мне недавний ONT.
Спасибо - у меня, к сожалению, нет цикла сообщений :)
Так что создайте его! Очередь сообщений устанавливается операционной системой после вызова :: GetMessage или :: PeekMessage.
Вы можете использовать очереди таймера (http://msdn.microsoft.com/en-us/library/ms686796.aspx). Они не требуют HWND.
Звучит интересно, приведите пример
Вместо использования таймеров пользовательского интерфейса (даже если вы можете использовать дескриптор окна NULL, как показано г-ном 1800-INFO) вы можете использовать объекты таймера ожидания ядра. См. CreateWaitableTimer в документации API. Затем их можно ожидать с помощью WaitForSingleObject или WaitForMultipleObjects и т. д., Что особенно полезно, если ваша служба уже ожидает внешних событий.
Если это не ясно из этой первой ссылки, функция SetWaitableTimer может связать процедуру завершения (обратный вызов пользователя) с таймером. Не забудьте использовать ... Ex версии WaitForMultipleObjects (и т. д.), Чтобы поток находился в состоянии "оповещения".
Звучит хорошо - я использовал очереди таймера, но я также прочитаю вашу ссылку. Спасибо!
Спасибо, я думаю, что TimerQueues может быть излишним, но это действительно зависит от того, как устроена остальная часть вашего сервиса. Если вы хотите, чтобы поток ThreadPool обрабатывал событие таймера, TimerQueues подойдет. Если у вас уже есть цикл вокруг WFMO или GetMessage, вы можете использовать другие варианты.
Вы просто время от времени пытаетесь «проснуться», чтобы поработать? Вы всегда можете использовать Sleep ().
Кроме того, у меня обычно есть поток, который находится в цикле while (1 == 1) со сном внутри. Там я могу проверить наличие запроса на отключение и других дополнительных операций. Вы можете использовать эту систему для отслеживания события или мьютекса рабочего потока в приложении.
Нет, служба обрабатывает данные в других потоках, мне просто нужно проверять состояние нескольких файлов каждую секунду.
Вероятно, излишний для вас, но ... Вы можете использовать ReadDirectoryChangesW для "прослушивания" изменений в файлах, а не для их опроса, это, вероятно, будет более эффективно, поскольку вы будете просыпаться только тогда, когда есть изменения для обработки, а не каждые ' x'ms ... Это сложнее настроить.
В одном из своих комментариев вы сказали, что «... служба обрабатывает данные в других потоках, мне просто нужно проверять состояние нескольких файлов каждую секунду».
Опрос не является оптимальным способом проверки состояния файла и отрицательно влияет на производительность системы. Хотя (иногда) возникают проблемы с выполнением этого по сети, вы должны проверить http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx или http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx, чтобы узнать, как это сделать, и http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx, чтобы узнать, почему вам следует это сделать.
Да спасибо. Я знаю об этих функциях, и вы, вероятно, правы, я должен быть умнее и использовать их. Поскольку у меня нет контроля над файлом, я могу только наблюдать за размером файла, но, честно говоря, я не опрашиваю его постоянно (только раз в секунду).
+1 за "бум идет динамит", но немного поработайте над форматированием