Таймер в сервисе win32 - PullRequest
       9

Таймер в сервисе win32

9 голосов
/ 22 октября 2008

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

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

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

Ответы [ 6 ]

15 голосов
/ 22 октября 2008

Вы можете использовать очереди таймера (http://msdn.microsoft.com/en-us/library/ms686796.aspx). Они не требуют HWND.

5 голосов
/ 22 октября 2008

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

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

4 голосов
/ 22 октября 2008

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

Обратный вызов Timer будет вызываться DispatchMessage. Этот вопрос напомнил мне о недавнем ONT .

1 голос
/ 23 октября 2008

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

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

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

Пример:

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

SetTimer (hwnd, IDT_TIMER1, 10000, (TIMERPROC) NULL);

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

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

{ 

    case IDT_TIMER1: 

        // Boom goes the dynamite

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

0 голосов
/ 22 октября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...