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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
9 169
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Пример:

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

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

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

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

{ 

    case IDT_TIMER1: 

        // Boom goes the dynamite

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

+1 за "бум идет динамит", но немного поработайте над форматированием

1800 INFORMATION 22.10.2008 04:31

Спасибо - в моем сервисе нет цикла сообщений, чтобы поймать сообщение :)

dennisV 22.10.2008 04:51

Так что создайте его! Очередь сообщений устанавливается операционной системой после вызова :: GetMessage или :: PeekMessage.

Johann Gerell 23.10.2008 01:22

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

Спасибо - у меня, к сожалению, нет цикла сообщений :)

dennisV 22.10.2008 04:51

Так что создайте его! Очередь сообщений устанавливается операционной системой после вызова :: GetMessage или :: PeekMessage.

Johann Gerell 23.10.2008 01:21
Ответ принят как подходящий

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

Звучит интересно, приведите пример

1800 INFORMATION 22.10.2008 04:35

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

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

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

dennisV 22.10.2008 04:52

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

Adam Mitz 22.10.2008 05:06

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

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

Нет, служба обрабатывает данные в других потоках, мне просто нужно проверять состояние нескольких файлов каждую секунду.

dennisV 22.10.2008 04:50

Вероятно, излишний для вас, но ... Вы можете использовать ReadDirectoryChangesW для "прослушивания" изменений в файлах, а не для их опроса, это, вероятно, будет более эффективно, поскольку вы будете просыпаться только тогда, когда есть изменения для обработки, а не каждые ' x'ms ... Это сложнее настроить.

Len Holgate 22.10.2008 12:03

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

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

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

dennisV 24.10.2008 02:31

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