Использование мультимедийного таймера
Интересная разновидность системных событий - высокоточный мультимедийный таймер. Гарантированный интервал срабатывания мультимедийных таймеров - около 10 миллисекунд против 50 миллисекунд обычных таймеров, устанавливаемых при помощи функции SetTimer. Кроме того, мультимедийные таймеры позволяют использовать обработчики, которые будут срабатывать в нужные интервалы, тогда как сообщения WM_TIMER от обычных таймеров идут через общую очередь. Если главный поток подвис, заснул или продолжительное время реагирует на какое-нибудь тяжелое сообщение, то таймеру придется ожидать, пока обработчик дойдет до него. Таким образом, добиться предсказуемой периодичности таймера будет очень сложно. Мультимедийные таймеры выполняются в собственном потоке, поэтому лишены перечисленных недостатков.Слова словами, но давайте проверим это на практике. Для этого в простом оконном приложении установим обычный таймер на интервал 1 миллисекунду, вместе с этим создадим мультимедийный таймер с таким же интервалом срабатывания. При каждом срабатывании каждого из этих таймеров будет увеличен соответствующий счетчик. По истечении определенного времени, например, 5 секунд, сравним результаты.
Обработчик окна будет выглядеть примерно так. Для удобства я оставил только минимально необходимый код.
Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_INITDIALOG
- je wminitdialog
- cmp [msg],WM_TIMER
- je wmtimer
- ...
- ...
- wminitdialog:
- ; Обнулить счетчики
- mov [dCntTim],0
- mov [dCntMM],0
- ; Получить начальное время
- invoke GetTickCount
- mov [dTime],eax
- ; Установить обычный таймер на интервал 1 мс
- invoke SetTimer,[hwnddlg],1,1,NULL
- ; Установить мультимедийный таймер на интервал 1 мс
- TIME_PERIODIC = 0x0001
- invoke timeSetEvent,1,1,TimeProc,777,TIME_PERIODIC
- ...
- ...
- wmtimer:
- ; Увеличить счетчик по событию WM_TIMER
- inc [dCntTim]
- ; Прошло 5 секунд?
- invoke GetTickCount
- sub eax,[dTime]
- cmp eax,5000
- jb processed
- jmp wmclose
- wmclose:
- ; Удалить оба счетчика
- invoke KillTimer,[hwnddlg],1
- invoke timeKillEvent,[hTimer]
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------
- ; Обработчик высокоточного таймера
- ;-----------------------------------------------------------
- proc TimeProc uTimerID:DWORD,uMsg:DWORD,dwUser:DWORD,dw1:DWORD,dw2:DWORD
- ; Увеличить счетчик по системному событию
- inc [dCntMM]
- ret
- endp
В приложении пример программы с исходным текстов, которая устанавливает два таймера и сравнивает количество их срабатываний.
Просмотров: 1301 | Комментариев: 4
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Виталий
(09.09.2022 в 18:48):
Очень благодарен за статью! 1к% это то, что мне сейчас нужно.
ManHunter
(03.09.2020 в 22:05):
Не статья, а опечатка на опечатке, уже сколько исправил. Вроде трезвый набирал :(
Владимир
(03.09.2020 в 21:47):
"вытокоточного" очапутка в тексте.
Сорри. С телефона, не могу Ctrl+Enter
Сорри. С телефона, не могу Ctrl+Enter
zdm
(26.08.2020 в 07:21):
Спасибо. Очень полезно.
Добавить комментарий
Заполните форму для добавления комментария