Click here to Skip to main content
15,844,754 members
Articles / Desktop Programming / MFC

TaskTimer - An Object to Monitor Task Execution

Rate me:
Please Sign up or sign in to vote.
4.38/5 (6 votes)
8 Aug 2002CPOL2 min read 88.3K   1.9K   66   10
An object that tracks a task's elapsed and remaining times, and execution state


This article describes TaskTimer, a lightweight object that lets you easily track a task's elapsed and remaining times. Although there are various CodeProject articles that describe this functionality, this article separates the GUI aspect of progress display from the time computation. Because TaskTimer isn't part of any control or dialog, you can make use of its functionality in any user interface. TaskTimer also handles pausing and restarting the task being timed.

The sample application also demonstrates a couple of techniques that can help give your app a more professional look and feel:

  • Making a single threaded app responsive while performing a long task
  • Flicker free updating of progress text

How to Use TaskTimer

TaskTimer is easy to use! First, declare an instance of the object in your dialog.

TaskTimer   m_taskTimer;  // TaskTimer object used for timing

When you want to start timing, call the object's start() method.

// Start timing

Every now and then, inform the object of your task's progress by calling its updateProgress() method.

// Update the task progress
nProgress = ...;
m_taskTimer.updateProgress (nProgress);

To determine the task's elapsed and estimated remaining times, just call the appropriate methods.

// Get elapsed and remaining times
long nElapsedTimeInSecs = m_taskTimer.getElapsedTime();
long nRemainingTimeInSecs = m_taskTimer.getRemainingTime();

To display a user friendly time interval instead of the number of seconds, use the alternate form of these methods.

// Display user friendly remaining time
CString strRemaining;
m_taskTimer.getRemainingTime (strRemaining);
SetDlgItemText (IDC_TIME_REMAINING, strRemaining);

To indicate that the task has been paused, resumed or stopped, call the appropriate method.

// User pressed "Pause"

TaskTimer API

The TaskTimer API contains functions to control timing, update progress, and retrieve timing and task state information.

// Control timing
void  start();      // start timing
void  pause();      // pause timing
void  resume();     // resume timing
void  stop();       // stop timing

// Update progress
void  update();                       // update elapsed time

void  updateProgress                  // update progress
        (long nProgress);

void  updateProgress                  // update progress and get
        (long   nProgress,            // remaining time
         long&  nRemainingTime);

// Retrieve timing
long  getProgress();                  // return current progress

long  getElapsedTime();               // get elapsed time

void  getElapsedTime                  // get elapsed time as components
        (long&  nHours,
         long&  nMinutes,
         long&  nSeconds);

void  getElapsedTime                  // get elapsed time as formatted string
        (CString& strElapsed);

long  getRemainingTime();             // get remaining time

void  getRemainingTime                // get remaining time as components
        (long&  nHours,
         long&  nMinutes,
         long&  nSeconds);

void  getRemainingTime                // get remaining time as formatted string
        (CString& strRemaining);

// Retrieve task state
bool  isRunning();                    // is task running?
bool  isPaused();                     // is task paused?
bool  isStopped();                    // is task stopped?

Responding to User Input While Performing a Long Task

To make a single threaded app respond to user input while performing a long task (e.g., within a pushbutton command handler), break up the task into a number subtasks and execute each subtask within a loop. After executing a subtask, pump the message queue. If you allow the user to cancel the task, check for cancellation after pumping the message queue, and take appropriate action.

void CTaskTimer_DemoDlg::OnStart()
  // Start processing

  // For each of the 10 "subtasks" ...
  for (long nTaskIterator=1; (nTaskIterator <= 10); nTaskIterator++) {

      // Execute a subtask and update the task progress
      m_taskTimer.updateProgress (nTaskIterator * 10);

      // Pump the message queue
      MSG   msg;
      while (::PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))

      // Quit if user cancelled
      if (m_bCancelled) {

Flicker Free Updating of Progress Text

Although it's nice to provide your user with frequently updated progress information, constantly updating a static text control can produce annoying flickering. This simple function shows how to do away with flicker by only setting the control's text if it's changed.

void updateWindowText
  (CWnd*    pWnd,
   CString  strText)
  ASSERT (pWnd != NULL);
  CString strOldText;
  pWnd->GetWindowText (strOldText);
  if (strOldText != strText) {
      pWnd->SetWindowText (strText);

Revision History

  • 7th August, 2002: Added methods update(), getElapsedTime (CString&) and getRemainingTime (CString&)
  • 21st April, 2002: Bug fix: stop() was not updating the current time
  • 16th April, 2002: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Technical Lead
Canada Canada
Ravi Bhavnani is an ardent fan of Microsoft technologies who loves building Windows apps, especially PIMs, system utilities, and things that go bump on the Internet. During his career, Ravi has developed expert systems, desktop imaging apps, marketing automation software, EDA tools, a platform to help people find, analyze and understand information, trading software for institutional investors and advanced data visualization solutions. He currently works for a company that provides enterprise workforce management solutions to large clients.

His interests include the .NET framework, reasoning systems, financial analysis and algorithmic trading, NLP, HCI and UI design. Ravi holds a BS in Physics and Math and an MS in Computer Science and was a Microsoft MVP (C++ and C# in 2006 and 2007). He is also the co-inventor of 3 patents on software security and generating data visualization dashboards. His claim to fame is that he crafted CodeProject's "joke" forum post icon.

Ravi's biggest fear is that one day he might actually get a life, although the chances of that happening seem extremely remote.

Comments and Discussions

QuestionHow can find Time Taken for an Thread Pin
Renugopal24-May-05 1:31
Renugopal24-May-05 1:31 
AnswerRe: How can find Time Taken for an Thread Pin
Ravi Bhavnani24-May-05 3:06
professionalRavi Bhavnani24-May-05 3:06 
GeneralWill make the task even longer. Pin
WREY25-Mar-04 12:45
WREY25-Mar-04 12:45 
GeneralRe: Will make the task even longer. Pin
Ravi Bhavnani25-Mar-04 13:03
professionalRavi Bhavnani25-Mar-04 13:03 
GeneralThere is always one more bug... Pin
Ravi Bhavnani18-Apr-02 13:25
professionalRavi Bhavnani18-Apr-02 13:25 
GeneralFixed Pin
Ravi Bhavnani22-Apr-02 4:22
professionalRavi Bhavnani22-Apr-02 4:22 
GeneralElegant Pin
NormDroid16-Apr-02 21:58
professionalNormDroid16-Apr-02 21:58 
GeneralRe: Elegant Pin
Ravi Bhavnani17-Apr-02 4:00
professionalRavi Bhavnani17-Apr-02 4:00 
GeneralGood! Pin
Nish Nishant16-Apr-02 14:55
sitebuilderNish Nishant16-Apr-02 14:55 
GeneralRe: Good! Pin
Ravi Bhavnani17-Apr-02 4:01
professionalRavi Bhavnani17-Apr-02 4:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.