Попробовал с WaitableTimer, что-то не получается.
Написал с вызовом callback-функции:
SetWaitableTimer (hTimer, &tm, 0,
MyCompletionRoutine, // completion routine
&MyArgToCompletionRoutine, // completion routine parameter
0);
Нифига она не вызывается
Интервал ставил 15 секунд:
tm.QuadPart = -150000000;
Насторожила строка в MSDN:
The completion routine is executed by the thread that activates the timer using SetWaitableTimer. However, the thread must be in an alertable state.
Может, в данном случае этого "стейта" и нет...
Выдержать "паузу" в приложении.
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Удобнее использовать не голые Win32API-функции, а применить класс-обёртку на С++. Набери в поисковике что-нибудь типа "CWaitableTimer".
WaitableTimer по тому и Waitable, что предполагается его ждать функциями WaitFor..Object(s). А данном случае никакого смысла его использовать нету. Проще обычным Sleep или теми же Wait... с таймаутом необходимым - результат будет такой же. А именно блокировка потока до истечения какого-то времени. Если не хочется блокировать поток, то без цикла обработки сообщений не обойтись.
Но кстати тут и может пригодиться WaitableTimer чтобы ждать его в MsgWaitFor...
Вот пример из MSDN цикла сообщений с ожиданием событий
Можно создать WaitableTimer на 15 секунд например и передать его в эту функцию -
MessageLoop(&hTimer, 1); и она будет крутить цикл сообщений пока не пройдет 15 секунд (правда тогда "DoStuff (result - WAIT_OBJECT_0) ;" надо на "return" наверно заменить )
Но кстати тут и может пригодиться WaitableTimer чтобы ждать его в MsgWaitFor...
Вот пример из MSDN цикла сообщений с ожиданием событий
Код: Выделить всё
int MessageLoop (
HANDLE* lphObjects, // handles that need to be waited on
int cObjects // number of handles to wait on
)
{
// The message loop lasts until we get a WM_QUIT message,
// upon which we shall return from the function.
while (TRUE)
{
// block-local variable
DWORD result ;
MSG msg ;
// Read all of the messages in this next loop,
// removing each message as we read it.
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If it is a quit message, exit.
if (msg.message == WM_QUIT)
return 1;
// Otherwise, dispatch the message.
DispatchMessage(&msg);
} // End of PeekMessage while loop.
// Wait for any message sent or posted to this queue
// or for one of the passed handles be set to signaled.
result = MsgWaitForMultipleObjects(cObjects, lphObjects,
FALSE, INFINITE, QS_ALLINPUT);
// The result tells us the type of event we have.
if (result == (WAIT_OBJECT_0 + cObjects))
{
// New messages have arrived.
// Continue to the top of the always while loop to
// dispatch them and resume waiting.
continue;
}
else
{
// One of the handles became signaled.
DoStuff (result - WAIT_OBJECT_0) ;
} // End of else clause.
} // End of the always while loop.
} // End of function.
MessageLoop(&hTimer, 1); и она будет крутить цикл сообщений пока не пройдет 15 секунд (правда тогда "DoStuff (result - WAIT_OBJECT_0) ;" надо на "return" наверно заменить )
WinMain, Hawk,WinMain писал(а):Удобнее использовать не голые Win32API-функции, а применить класс-обёртку на С++. Набери в поисковике что-нибудь типа "CWaitableTimer".
я вот тоже, глядя на найденные примеры (как в MSDN, так и в интернете), вижу, что после запуска таймера тем или иным способом запускается "остановка (ожидание)" в денной точке. Без этого, похоже, не будет вызванна указанная callback-процедура. (Кстати, в большинство примеров вызов SetWaitableTimer происходит без указания callback-процедуры).
Например, в одном из примеров (MFC-dialog-based-приложения) таймер запускается при нажатии на кнопку окна. Т.е., стало быть (если копать "вглубь"), внутри оконной пр-ры-обработчика событий. И далее тут же стоит:
SleepEx (INFINITE, TRUE);
Callback-функция (указанная в SetWaitableTimer) вызывается, после чего SleepEx возвращает управление.
Убираю этот SleepEx (т.е. получаем, что программа покидает оконную пр-ру-обработчик до истечения указанного таймеру времени) - callback-пр-ра уже не вызывается!
А тебе так нужен callback? Исходя из твоей задачи он тебе не нужен совсем. А callback можно сделать и обычным SetTimer если так надо.
Мне хотелось бы "поспать" какой-то промежуток времени, выждать некоторый тайм-аут, (причем поспать "асинхронно", т.е. чтобы приложение в этот момент не "умирало", реагировало на другие "внешние воздействия"), после которого сделать нужные действия. Callback - это как вариант (поскольку именно callback имеется в WaitableTimer).Hawk писал(а):А тебе так нужен callback? Исходя из твоей задачи он тебе не нужен совсем. А callback можно сделать и обычным SetTimer если так надо.
Обычный SetTimer - это тоже вариант, но меня несколько смущало (см. самое первое мое сообщение в этой теме), что если такие ситуации (т.е. необходимость выдерживать тайм-ауты) будут повторяться в программе часто, то придется часто делать SetTimer и (после истечения тайм-аута) KillTimer. Смущало, не есть ли плохо (для Windows, ресурсов или еще-чего-нибудь) такое постоянное "дергание" (установка/"убийство") виндовых таймеров.