Processamento de loop ocioso

Muitos aplicativos executam processamento longo "em segundo plano". Às vezes, considerações de desempenho determinam o uso de multithreading para esse tipo de trabalho. Os threads envolvem sobrecarga extra de desenvolvimento, portanto não são recomendados para tarefas simples, como o trabalho de tempo ocioso que o MFC faz na função OnIdle. Este artigo se concentra no processamento ocioso. Para saber mais sobre multithreading, confira Tópicos sobre multithreading.

Alguns tipos de processamento em segundo plano são feitos adequadamente durante intervalos em que o usuário não está interagindo de outra forma com o aplicativo. Em um aplicativo desenvolvido para o sistema operacional Microsoft Windows, o pode executar o processamento de tempo ocioso dividindo um processo longo em muitos fragmentos pequenos. Depois de processar cada fragmento, o aplicativo gera um controle de execução para o Windows usando um loop PeekMessage.

Este artigo explica duas maneiras de fazer o processamento ocioso no aplicativo:

  • Usando PeekMessage no loop de mensagem principal do MFC.

  • Inserindo outro loop PeekMessage em outro lugar do aplicativo.

PeekMessage no loop de mensagem do MFC

Em um aplicativo desenvolvido com MFC, o loop de mensagem principal na classe CWinThread contém um loop de mensagem que chama a API do Win32 PeekMessage. Esse loop também chama a função membro OnIdle entre mensagens CWinThread. Um aplicativo pode processar mensagens nesse tempo ocioso substituindo a função OnIdle.

Observação

Run, OnIdle e certas outras funções membros agora são membros da classe CWinThread, e não da classe CWinApp. CWinApp é derivado de CWinThread.

Para obter mais informações sobre como executar o processamento ocioso, consulte OnIdle na Referência do MFC.

PeekMessage em outro lugar no aplicativo

Outro método para executar o processamento ocioso em um aplicativo envolve a inserção de um loop de mensagem em uma de suas funções. Esse loop de mensagem é muito semelhante ao loop de mensagem principal do MFC, encontrado em CWinThread::Run. Isso significa que esse loop em um aplicativo desenvolvido com MFC deve executar muitas das mesmas funções que o loop de mensagem principal. O seguinte fragmento de código demonstra como escrever um loop de mensagem compatível com o 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
}

Esse código, inserido em uma função, faz loops desde que haja processamento ocioso a ser feito. Dentro desse loop, um loop aninhado chama PeekMessage repetidamente. Desde que essa chamada retorne um valor diferente de zero, o loop chamará CWinThread::PumpMessage para executar a tradução e a expedição de mensagens normais. Embora PumpMessage não esteja documentado, você pode examinar seu código-fonte no arquivo ThrdCore.Cpp no diretório \atlmfc\src\mfc da instalação do Visual C++.

Depois que o loop interno termina, o loop externo executa o processamento ocioso com uma ou mais chamadas para OnIdle. A primeira chamada é para fins do MFC. Você pode fazer chamadas adicionais para OnIdle para fazer seu trabalho em segundo plano.

Para obter mais informações sobre como executar o processamento ocioso, consulte OnIdle na Biblioteca de Referência do MFC.

Confira também

Tópicos gerais do MFC