Обработка пустых циклов
Многие приложения выполняют длинную обработку "в фоновом режиме". Иногда рекомендации по повышению производительности определяют использование многопоточных операций для такой работы. Потоки включают дополнительные затраты на разработку, поэтому они не рекомендуется для простых задач, таких как работа бездействия, которую MFC выполняет в функции OnIdle . В этой статье основное внимание уделяется бездействующей обработке. Дополнительные сведения о многопоточности см. в разделах с многопоточной информацией.
Некоторые виды фоновой обработки выполняются соответствующим образом во время интервалов, которые пользователь не взаимодействует с приложением. В приложении, разработанном для операционной системы Microsoft Windows, приложение может выполнять обработку бездействия, разделив длительный процесс на множество небольших фрагментов. После обработки каждого фрагмента приложение получает управление выполнением в Windows с помощью цикла PeekMessage .
В этой статье объясняется два способа простоя обработки в приложении:
Использование PeekMessage в основном цикле сообщений MFC.
Внедрение другого цикла PeekMessage где-то еще в приложении.
ПросмотрMessage в цикле сообщений MFC
В приложении, разработанном с помощью MFC, основной цикл сообщений в CWinThread
классе содержит цикл сообщений, вызывающий API Win32 PeekMessage . Этот цикл также вызывает функцию-член OnIdle
CWinThread
между сообщениями. Приложение может обрабатывать сообщения в это время простоя, переопределяя функцию OnIdle
.
Примечание.
Run
, OnIdle
и некоторые другие функции-члены теперь являются членами класса CWinThread
, а не класса CWinApp
. Класс CWinApp
является производным от CWinThread
.
Дополнительные сведения о выполнении бездействия см. в разделе OnIdle в справочнике по MFC.
PeekMessage в другом месте приложения
Другой метод для выполнения простоя обработки в приложении включает внедрение цикла сообщений в одну из ваших функций. Этот цикл сообщений очень похож на основной цикл сообщений MFC, найденный в CWinThread::Run. Это означает, что такой цикл в приложении, разработанном с помощью MFC, должен выполнять многие из таких же функций, что и основной цикл сообщений. В следующем фрагменте кода показано написание цикла сообщений, совместимого с MFC:
BOOL bDoingBackgroundProcessing = TRUE;
while (bDoingBackgroundProcessing)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!AfxGetApp()->PumpMessage())
{
bDoingBackgroundProcessing = FALSE;
::PostQuitMessage(0);
break;
}
}
// let MFC do its idle processing
LONG lIdle = 0;
while (AfxGetApp()->OnIdle(lIdle++))
;
// Perform some background processing here
// using another call to OnIdle
}
Этот код, внедренный в функцию, циклирует до тех пор, пока требуется неактивная обработка. В этом цикле вложенный цикл многократно вызывается PeekMessage
. Если этот вызов возвращает ненулевое значение, вызовы CWinThread::PumpMessage
цикла для выполнения обычного перевода сообщений и отправки сообщений. Несмотря PumpMessage
на то, что он не указан, его исходный код можно просмотреть в файле ThrdCore.Cpp в каталоге \atlmfc\src\mfc установки Visual C++.
После завершения внутреннего цикла внешний цикл выполняет неактивную обработку с одним или несколькими вызовами OnIdle
. Первый вызов предназначен для целей MFC. Вы можете выполнять дополнительные вызовы для OnIdle
выполнения собственной фоновой работы.
Дополнительные сведения о выполнении бездействия см. в разделе OnIdle в справочнике по библиотеке MFC.