| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > SetTimer. механизм срабатывания callback |
| Автор: Lexicss 19.2.2008, 16:13 |
| UINT SetTimer( HWND hWnd, // handle of window for timer messages UINT nIDEvent, // timer identifier UINT uElapse, // time-out value TIMERPROC lpTimerFunc // address of timer procedure ); Функция SetTimer. Вызвав её с нулевыми параметрами дискриптора окна и идентифекатора, но с указанием адреса функции - выполняет функцию в потоке, который вызвал SetTimer, через указанный uElapse промежуток времени. Вопрос: Как ведёт себя вызваший поток, когда срабатывает таймер? Он ведь в это время может выполнять какие-то инструкции, а необходимо непременно выполнить callback function... Вообщем, как осуществляется выполнение callback-функции вызванной таймером? Не могу пока найти никакой информации по этому. |
| Автор: Rennigth 19.2.2008, 16:19 | ||
Lexicss,
|
| Автор: Alexeis 19.2.2008, 16:20 | ||
Сообщение WM_TIMER по любому попадет в очередь сообщений потока и дефолтный обработчик должен вывать калбэк, если очереди сообщений нет, то фиг вам будет, а не калбэк |
| Автор: Lexicss 19.2.2008, 16:52 |
| Rennigth, ну у меня ж lpTimerFunc = не NULL. Alexeis, Как я этот механизм понимаю: Значит любой поток имеет дефолтный обработчик. И когда в очередь сообщений текущего потока попадает WM_TIMER, то этот дефолтный обработчик и вызывает callback-функцию. Но я всё равно и не понял, как прерывается работа потока? Например, вызвал я SetTimer в главном потоке. Сработал таймер, обработчик спаймал WM_TIMER и тут же принялся выполнять колбэк-функцию, а когда выполнил, то вернулся снова к своим делам? Так что ли? |
| Автор: Rennigth 19.2.2008, 17:02 |
Если есть в потоке очередь сообщений, и поток в данный момент не занят чем либо еще то рано или поздно он поймает WM_TIMER и выполнит твою lpTimerFunc. Выролнение какого-то кода не прервется, если конечно не выполнять всяких Application.ProcessMessages. |
| Автор: Lexicss 19.2.2008, 17:03 |
| Alexeis, Где-то я такое слышал что нельзя поток просто так взять и прерывать в случайный момент времени. Добавлено через 7 минут и 14 секунд Rennigth, Тогда смысл такой: поток перебирает свою очередь и обрабатывает один за другим свои сообщения. т.о. и обрабатывает колбэк-функцию, когда добирается до WM_TIMER. Т.е. никакого механизма с тревожным ожиданием потока здесь нет? |
| Автор: Alexeis 19.2.2008, 17:13 |
| Получается, что если назначено окно, то вызывает API функция DefWindowProc если нет окна, то DispatchMessage |
| Автор: Lexicss 19.2.2008, 17:32 |
| Есть ещё такое понятие как поступление APC-запроса в очеред с указанием адреса функции и параметра. В SetTimer и есть этот механизм? Или здесь совсем нето. wm_timer сообщение в параметрах хранит адрес функции для обработчика? Добавлено через 2 минуты и 49 секунд Т.е. поток при срабатывании таймера не вводится в режим тревожного ожидания? (хочу просто чётко с этим разобраться) |
| Автор: MetalFan 19.2.2008, 17:48 | ||
нет, этот механизм в таймерах ожидания и в очередях таймеров применяться afaik (Waitable Timer, Timer Queue) |
| Автор: Rennigth 19.2.2008, 17:54 | ||||||
Нет.
Да.
Если честно незнаю что ты имеешь ввиду под понятием "тревожного ожидания" Вообщем юзай SetTimer/KillTimer и не тревожся. Он не очень точный конечно, есть другие, более точные, например мультимедийный таймер, вот они уже работаеют по всяким прерываниям и т.д.(не особо знаю механизм), и тогда уже могут возникать проблемы и может понадобится подобие синхронизации... |
| Автор: Lexicss 19.2.2008, 18:04 |
| MetalFan, как это можно проверить на примере? |
| Автор: MetalFan 19.2.2008, 19:07 |
| Lexicss, что проверить? msdn уже нет доверия? ) |
| Автор: bems 19.2.2008, 19:16 | ||
|
| Автор: MetalFan 19.2.2008, 22:06 |
сначало необходимо создать очередь сообщений. вызвав GetMessage (PeekMessage) |
| Автор: Lexicss 20.2.2008, 08:53 |
Типа того |
| Автор: MetalFan 20.2.2008, 09:33 |
ну так убеждайся. создай допустим таймер ожидания (CreateWaitableTimer, SetWaitableTimer). переведи поток в "тревожное состояние" и убедись) |
| Автор: Lexicss 20.2.2008, 15:23 |
| C SetTimer разобрался и проверил. Всё действительно так и есть: Когда срабатывает таймер, генерируется сообщение WM_TIMER с параметрами идентификатора этого таймера и адресом функции. Когда обработчик текущего потока обнаруживает в очереди это сообщение, то вызывает callback-функцию. Если в этом потоке присутсвуют свои обработчики сообщений, не имеющие ограничений, то они тоже срабатывают. Вообщем, вопрос решён. Спасибо большое всем за разъяснение. P.S.: С SetWaitableTimer щас эксперементирую. Но это уже будет отдельная тема(если опять во что-нибудь уткнусь). |