许多应用程序“在后台”执行较长的处理。有时,性能注意事项决定了对此类工作使用多线程处理。 线程涉及额外的开发开销,因此不建议将线程用于简单的任务,例如 MFC 在 OnIdle 函数中执行的空闲时间工作。 本文重点介绍空闲处理。 有关多线程的详细信息,请参阅 多线程主题。
某些类型的后台处理是在用户不与应用程序交互的时间间隔内适当完成的。 在为 Microsoft Windows作系统开发的应用程序中,应用程序可以通过将漫长的过程拆分成许多小片段来执行空闲时间处理。 处理每个片段后,应用程序使用 PeekMessage 循环向 Windows 生成执行控件。
本文介绍在应用程序中执行空闲处理的两种方法:
在 MFC 的主消息循环中使用 PeekMessage 。
在应用程序中其他位置嵌入另一个 PeekMessage 循环。
MFC 消息循环中的 PeekMessage
在使用 MFC 开发的应用程序中,类中的 CWinThread
主消息循环包含调用 PeekMessage Win32 API 的消息循环。 此循环还调用 OnIdle
消息之间的成员函数 CWinThread
。 应用程序可以通过重写 OnIdle
函数来处理此空闲时间的消息。
注释
Run
、 OnIdle
和某些其他成员函数现在是类 CWinThread
的成员,而不是类 CWinApp
的成员。
CWinApp
派生自 CWinThread
。
有关执行空闲处理的详细信息,请参阅 MFC 参考中的 OnIdle。
应用程序中的其他位置的 PeekMessage
在应用程序中执行空闲处理的另一种方法涉及在某个函数中嵌入消息循环。 此消息循环与在 CWinThread::Run 中找到的 MFC 主消息循环非常相似。 这意味着,使用 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
未记录,但可以在 Visual C++ 安装的 \atlmfc\src\mfc 目录中的 ThrdCore.Cpp 文件中检查其源代码。
内部循环结束后,外部循环将执行空闲处理,同时调用一个或多个调用 OnIdle
。 第一个调用用于 MFC 的目的。 可以进行其他调用以 OnIdle
执行自己的后台工作。
有关执行空闲处理的详细信息,请参阅 MFC 库参考中的 OnIdle 。