TTimer. Повторно используемый обработчик событий OnTimer?

У меня есть TTimer в моем приложении, которое стреляет каждые 2 секунды и называет мой обработчик событий, HandleTimerEvent (). HandleTimerEvent () функция изменяет совместно используемые ресурсы и может занять 10-е секунд для выполнения перед возвратом. Кроме того, я называю Сон () в конечном счете обработчиком для отказа от процессора время от времени.

Я не уверен, как работы объекта TTimer разработчика C++ когда дело доходит до вызова событий, таким образом, сценарий я просто объяснил, имеют меня взгляды, особенно, называют ли HandleTimerEvent (), прежде чем предшествующий вызов возвратился.

Вопрос сводится к нескольким вещам.

TTimer возражает очереди события?

Может вызов объектов TTimer мой обработчик событий, прежде чем предшествующий вызов возвратился?

18
задан Rob Kennedy 22 July 2010 в 17:36
поделиться

2 ответа

Этот ответ предполагает, что TTimer все еще реализован для использования сообщений WM_Timer. Если реализация изменилась (с 2005 года), пожалуйста, не обращайте внимания.

Нет, объект TTimer не ставит события в очередь. Он управляется сообщением Windows WM_Timer, а Windows не позволяет сообщениям WM_TIMER накапливаться в очереди сообщений. Если наступает следующий интервал таймера и Windows видит, что сообщение WM_Timer уже находится в очереди сообщений приложения, она не добавляет еще одно сообщение WM_Timer в очередь. (То же самое для WM_Paint, btw)

Да, возможно, что событие TTimer.OnTimer будет запущено, даже если предыдущий обработчик события все еще выполняется. Если вы сделаете что-нибудь в обработчике события, что позволит приложению обрабатывать сообщения, то событие таймера может быть вызвано повторно. Самое очевидное - если ваш обработчик событий вызывает Application.ProcessMessages, но все может быть гораздо тоньше - если все, что вы вызываете в обработчике событий, внутренне вызывает Application.ProcessMessages, или вызывает PeekMessage/GetMessage + DispatchMessage, или открывает модальный диалог, или вызывает COM интерфейс, который связан с внепроцессным COM объектом, то сообщения в очереди сообщений вашего приложения будут обработаны, и это может включать ваше следующее сообщение WM_Timer.

Простым решением является отключение объекта таймера при входе в обработчик события таймера и повторное включение его при выходе из обработчика события таймера. Это предотвратит появление сообщений таймера, пока обработчик событий продолжает работать, независимо от особенностей обработки сообщений в вашем коде.

32
ответ дан 30 November 2019 в 07:38
поделиться

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

2
ответ дан 30 November 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: