Будет ли CDialog:SetTimer() блокировать поток, если KillTimer() никогда не вызывается?

#c #mfc #thread-safety

#c #mfc #безопасность потоков

Вопрос:

 BOOL CMemeDlg::PreTranslateMessage(MSG* pMsg)
{
    CString csMessage;
    if (pMsg->message == WM_KEYDOWN)
    {
        if (pMsg->wParam == VK_HOME)
        {
            KillTimer(TIMER_ID_FIELD); 
            SetTimer(TIMER_ID_FIELD, 500, NULL); 
            return true;
        }
    }

    return CDialog::PreTranslateMessage(pMsg);
}
 

В этом фрагменте кода будет ли таймер блокировать поток, предполагая, что KillTimer в потоке кода нет другого другого?

Ответ №1:

Если KillTimer() его вообще нет, SetTimer() просто сбросит существующий таймер, если он уже существует. Таким образом, вы не собираетесь перегружать поток несколькими таймерами.

WM_TIMER Сообщение является синтезированным сообщением. Когда извлечение сообщений выполняется с помощью (Get|Peek)Message() и в очереди нет доступных фактических сообщений (или если извлечение сообщений фильтруется WM_(SYS)TIMER специально), таймер проверяется, и фактическое WM_TIMER сообщение генерируется в очереди сообщений, только если таймер истек.

Итак, пока вы обрабатываете эти WM_TIMER сообщения должным образом, вы не будете перегружать свой поток ненужной обработкой таймера.

WM_TIMER Просто будьте осторожны, чтобы не выполнять много запросов на получение сообщений, которые игнорируются, иначе вы можете заполнить свою очередь сообщений (см. Несмотря на то, что сообщения о перемещении мыши, рисовании и таймере генерируются по требованию, они все равно могут оказаться в вашей очереди и почему моя очередь сообщенийполно сообщений WM_TIMER?.

Ответ №2:

Нет. WM_TIMER Сообщение будет отправляться только каждые 500 мсек.

Если обработчик легкий, вы даже не увидите никаких действий в диспетчере задач.