2008-10-22 3 views
9

Может ли кто-нибудь указать мне самый простой способ иметь таймер в службе Win32?Таймер в службе win32

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

Заранее спасибо.

ответ

1

Вы можете использовать SetTimer для установки таймера, а затем поймать сообщение WM_TIMER в своем контуре сообщения.

Пример:

// Установка таймера истекает через 10 секунд

SetTimer (HWND, IDT_TIMER1, 10000, (TimerProc) NULL);

... затем в цикле сообщений:

переключатель (WPARAM)

{ 

    case IDT_TIMER1: 

     // Boom goes the dynamite 

Вы также можете decleare функцию типа TimerProc и что можно назвать, когда таймер истекает, если вы не» t хотите выполнить обработку цикла сообщений.

+1

+1 для «стрела идет динамит», но немного работает на вашем форматировании – 2008-10-22 00:31:13

+0

Спасибо - в моем сервисе нет цикла сообщений, чтобы поймать сообщение, хотя :) – dennisV 2008-10-22 00:51:39

+0

Так что создайте его! Очередь сообщений настраивается os после вызова :: GetMessage или :: PeekMessage. – 2008-10-22 21:22:13

3

Вы можете отправить свой основной поток сообщений 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.

+0

Спасибо - у меня нет кейса сообщений, к сожалению :) – dennisV 2008-10-22 00:51:05

+0

Так что создайте его! Очередь сообщений настраивается os после вызова :: GetMessage или :: PeekMessage. – 2008-10-22 21:21:42

5

Вместо использования таймеров пользовательского интерфейса (хотя вы можете использовать дескриптор окна NULL, как показано г-ном 1800-INFO), вы можете использовать объекты, возвращаемые таймером ядра. См. CreateWaitableTimer в документах API. Затем их можно ждать - с использованием WaitForSingleObject или WaitForMultipleObjects и т. Д., Что особенно полезно, если это уже то, как ваш сервис ждет внешних событий.

Если из этой первой ссылки не ясно, функция SetWaitableTimer может связывать процедуру завершения (пользовательский обратный вызов) с таймером. Не забудьте использовать ... Ex-версии WaitForMultipleObjects (и т. Д.), Чтобы поток находился в «предупреждаемом» состоянии.

0

Вы просто пытаетесь «проснуться» время от времени, чтобы сделать какую-то работу? Вы всегда можете использовать Sleep().

Кроме того, у меня, как правило, есть поток, который в то время (1 == 1) цикл со сном внутри. Там я могу проверить запрос на завершение работы и другую утилизацию. Вы можете использовать эту систему, чтобы щекотать событие или мьютексы для рабочего потока в приложении.

1

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

Опрос не является оптимальным способом проверки состояния файла и будет отрицательно влиять на производительность системы.Хотя есть (иногда) проблемы с этим по сетям, вы должны проверить 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 за то, почему вы должны.