空闲循环处理

许多应用程序“在后台”执行较长的处理。有时,性能注意事项决定了对此类工作使用多线程处理。 线程涉及额外的开发开销,因此不建议将线程用于简单的任务,例如 MFC 在 OnIdle 函数中执行的空闲时间工作。 本文将重点介绍空闲处理。 有关多线程的详细信息,请参阅 多线程主题

某些类型的后台处理是在用户不与应用程序交互的时间间隔内适当完成的。 在为 Microsoft Windows作系统开发的应用程序中,应用程序可以通过将漫长的过程拆分成许多小片段来执行空闲时间处理。 处理每个片段后,应用程序使用 PeekMessage 循环向 Windows 生成执行控件。

本文介绍在应用程序中执行空闲处理的两种方法:

  • 在 MFC 的主消息循环中使用 PeekMessage

  • 在应用程序中其他位置嵌入另一个 PeekMessage 循环。

MFC 消息循环中的 PeekMessage

在使用 MFC 开发的应用程序中,类中的 CWinThread 主消息循环包含调用 PeekMessage Win32 API 的消息循环。 此循环还在消息之间调用 OnIdle 的成员函数 CWinThread。 应用程序可通过重写 OnIdle 函数处理此空闲时间中的消息。

注释

RunOnIdle和某些其他成员函数现在是类 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

另请参阅

常规 MFC 主题