Idle Loop Processing

Environment:

Introduction

Many applications perform lengthy processing "in the background." Sometimes, performance considerations dictate using multithreading for such work. Threads involve extra development overhead, so they are not recommended for simple tasks such as the idle-time work that MFC does in the OnIdle function. This article focuses on a simple idle processing technique using the PeekMessage and PumpMessage functions.

Some kinds of background processing are appropriately done during intervals when the user is not otherwise interacting with the application. In an application developed for the Microsoft Windows operating system, an application can perform idle-time processing by splitting a lengthy process into many small fragments. After processing each fragment, the application yields execution control to Windows by using a PeekMessage loop.

This small code example surrenders execution of the macro so that the operating system can process other events. This function passes control from the application to the operating system.

Some instances in which this function may be useful include the following:

  • Hardware I/O
  • Delay Loops
  • Operating System Calls
  • DDE Deadlocking

Code Manifesto

PeekMessage

The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

PumpMessage

Although the PumpMessage API is undocumented, you can examine its source code in the ThrdCore.Cpp file in MFC\Src relative to your Visual C++ installation.

Using PeekMessage

Here, embed the message loop in one of your functions. This message loop is very similar to MFC's main message loop, found in CWinThread::Run. That means that such a loop in an application developed with MFC must perform many of the same functions as the main message loop.

void DoEvents()
  {
    MSG dispatch;
    while (::PeekMessage( &dispatch, NULL, 0, 0, PM_NOREMOVE))
      {
        if (!AfxGetThread()->PumpMessage());
      }
  }

The code is embedded in a function named DoEvents(); it loops as long as there is idle processing to do. Within that loop, a nested loop repeatedly calls PeekMessage. As long as that call returns a non-zero value, the loop calls WinThread::PumpMessage to perform normal message translation and dispatching. AFter the inner loop ends, the outer loop performs idle processing with one or more calls. Declare and call DoEvents() from your own function.

One more thing, you might encounter a warning C4390 during compile, asking you to satisfy it with a controlled statement. The remedy is simple; you may add your own control statement inside the block or simply ignore it.

Any good, bad, or ugly feedback will be appreciated. If you think I have left out something or you have even some better ideas, please feel free to e-mail me at asceder@yahoo.com.



Comments

  • Idle Loop Processing

    Posted by Legacy on 12/08/2003 12:00am

    Originally posted by: dagza

    This little piece of code has made the day!!!

    Reply
  • J.R is right again: I've seen the code elsewhere

    Posted by Legacy on 10/09/2002 12:00am

    Originally posted by: Christian

    This code is 'leant' from Microsoft, so what is the article about ?

    Christian

    Reply
  • J.R. is right this is not idle processing...

    Posted by Legacy on 09/26/2002 12:00am

    Originally posted by: Keith V

    I have done a LOT of OnIdle() processing and yes it IS a lot simpler that multithreading.
    
    

    But this example is not using OnIdle()

    I use a dispatcher within the DoIdle()method of my CWinApp derived class that calls the appropriate code.

    Like this where DoCalculate() does the actual processing

    BOOL CMyAppBase::OnIdle(LONG lCount)
    {

    if (!CWinApp::OnIdle(lCount))
    {
    m_pMyProcessingClass->DoCalculate();
    }

    return TRUE;
    }

    Reply
  • Not Idle, you must mean processing the message queue while the application is busy...

    Posted by Legacy on 09/25/2002 12:00am

    Originally posted by: J.R.

    Hello!
    The title is wrong!
    Not Idle, you must mean processing the message queue while the application is busy!
    This code comes from Microsoft, in the Progress Dialog Control!

    Reply
  • What does this line mean?

    Posted by Legacy on 09/24/2002 12:00am

    Originally posted by: Alex F

    Please explain why do you need "if" in this line:
    if (!AfxGetThread()->PumpMessage());

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds