CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    Sep 2003
    Posts
    280

    non-period timer

    I create a timer with the specified time-out value. When a timer expires, the OnDoSomething function is called. Sometimes, the OnDoSomething function takes more time than the specified time-out value. For examle, the sepcified time-out value is 50, but the time OnDoSomething takes is 70. I want to let OnDoSomething be re-called when it finishes. Can I do that?

  2. #2
    Join Date
    May 2005
    Posts
    364

    Re: non-period timer

    Dont worry, Your timer always initiates the trigger at exact time and you will be getting more than one OneDoSomething within 70ms time.

    You don't have to do anything, your timer takes care of triggering that function in time.

    --Dan
    Dan

  3. #3
    Join Date
    Sep 2003
    Posts
    280

    Re: non-period timer

    Quote Originally Posted by danandu
    Dont worry, Your timer always initiates the trigger at exact time and you will be getting more than one OneDoSomething within 70ms time.

    You don't have to do anything, your timer takes care of triggering that function in time.
    --Dan
    Will the timer trigger that function in time, even if that function is still running?
    I just want to trigger that function again after that function finished.

  4. #4
    Join Date
    Oct 2005
    Location
    Bangalore
    Posts
    1,051

    Re: non-period timer

    Quote Originally Posted by Cooker
    Will the timer trigger that function in time, even if that function is still running? I just want to trigger that function again after that function finished.
    Thats why you will have to be carefull when using timers. The timer will always call your function irrespective if its running or not, but its your responsibility as a programmer to see that, before the timer can fire again, the earlier instance has been completed. Otherwise your function has techinically not finished executing and hance you will not be able to see the desired output.
    - Sreehari
    "Sometimes I think the surest sign that intelligent life exists elsewhere in the universe is that none of it has tried to contact us."
    " Everybody is sent to Earth on a purpose. I am so Lagging behind that i won't die." – Calvin

  5. #5
    Join Date
    May 2005
    Posts
    364

    Re: non-period timer

    If ur function is engaged in even after the timer trigger time elapsed, then you will not be able to access the second function which the timer has triggered. And this goes on and on. To overcome this problem Use threads inside the timer events. The background thread will be running and still you can access your foreground.
    Dan

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: non-period timer

    Quote Originally Posted by Cooker
    Will the timer trigger that function in time, even if that function is still running?
    I just want to trigger that function again after that function finished.
    While it won't get called again immediately after it finishes, the timer will call your function on the next timer click. In order to prevent your method from getting called again before it's finished from a previous timer call, just add a guard block.

    Code:
    // Preventing reentrancy with a guard block
    void CMFCTempDlg::OnTimer(UINT_PTR nIDEvent)
    {
      if( m_bInTimer ) return;
     
      m_bInTimer = TRUE;
     
    //
      // Do timer work here
      //
     
      m_bInTimer = FALSE;
     
    }

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: non-period timer

    Quote Originally Posted by danandu
    If ur function is engaged in even after the timer trigger time elapsed, then you will not be able to access the second function which the timer has triggered. And this goes on and on. To overcome this problem Use threads inside the timer events. The background thread will be running and still you can access your foreground.
    I don't see how using threads can help here. Can you explain further?

  8. #8
    Join Date
    Sep 2003
    Posts
    280

    Re: non-period timer

    Quote Originally Posted by Arjay
    While it won't get called again immediately after it finishes, the timer will call your function on the next timer click. In order to prevent your method from getting called again before it's finished from a previous timer call, just add a guard block.

    Code:
    // Preventing reentrancy with a guard block
    void CMFCTempDlg::OnTimer(UINT_PTR nIDEvent)
    {
      if( m_bInTimer ) return;
     
      m_bInTimer = TRUE;
     
    //
      // Do timer work here
      //
     
      m_bInTimer = FALSE;
     
    }
    When OnTimer is still running, the timer trigger that function again. Will the OnTimer function be called again? If not, how can it know the value of m_bInTimer ?

  9. #9
    Join Date
    May 2005
    Posts
    364

    Re: non-period timer

    Quote Originally Posted by Arjay
    I don't see how using threads can help here. Can you explain further?
    We know that the timer is regularly ticking at a fixed time (say 1ms)

    Call the thread in the timer function.

    But restrict this by using a flag setting.

    Check this flag for every tick (1ms) inside the timer event.

    if the flag, says the thread is over, then call the thread again!.

    Eureka! you can still execute your function without worrying about timer ticks and without losing any function.

    --Dan
    Dan

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: non-period timer

    Quote Originally Posted by Cooker
    When OnTimer is still running, the timer trigger that function again. Will the OnTimer function be called again? If not, how can it know the value of m_bInTimer ?
    I sure thought it was reentrant, but it doesn't look like it is. I set up a little test app with a guard in the OnTimer handler and it appears that the OS won't call the OnTimer again until it's returned. I thought this behavior was different in the NT4.0 /Win9x timeframe as it seemed to by it used to be reentrant and you needed to guard it. Anyway, on my Win2003 server machine it doesn't seem to be the case.

    Here's what I used:

    Code:
    void CMFCTempDlg::OnBnClickedOk()
    {
      UINT_PTR uiTimer = 0;
     
      // Start the 100ms timer
      SetTimer( uiTimer, 100, 0 );
    }
     
    void CMFCTempDlg::OnTimer(UINT_PTR nIDEvent)
    {
      TCHAR szTime[9] = { 0 };
     
      _tstrtime_s( szTime, 9 );
     
      TRACE1( "B: %s\n", szTime );
     
      if( m_bInTimer )
      {
    	TRACE( _T("Timer Skipped\n") );
    	return;
      }
     
      TRACE1( "A: %s\n", szTime );
      _tstrtime_s( szTime, 9 );
     
      m_bInTimer = TRUE;
     
      // Waste some cycles here (should take longer than 100ms)
      for( int x = 0; x < 100000000; x++ )
      {
    	Sleep( 0 );
      }
     
      m_bInTimer = FALSE;
    
     
      CDialog::OnTimer(nIDEvent);
    }
    Here's the output
    B: 01:17:31
    A: 01:17:31
    B: 01:17:34
    A: 01:17:34
    B: 01:17:37
    A: 01:17:37
    B: 01:17:40
    A: 01:17:40

    Last edited by Arjay; March 24th, 2007 at 03:23 AM.

  11. #11
    Join Date
    Jan 2002
    Location
    Houston, TX
    Posts
    1,421

    Re: non-period timer

    There is yet another possible approach to your problem. As soon as you enter the OnDoSomething function, kill the timer. This stops additional timer events from occurring.

    Just before exiting your OnDoSomething, set the timer again with the desired value.

    Hope that helps.
    Be sure to rate those who help!
    -------------------------------------------------------------
    Karl - WK5M
    PP-ASEL-IA (N43CS)
    PGP Key: 0xDB02E193
    PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193

  12. #12
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: non-period timer

    1) As to the re-entrncy, it depends on the type of timer. If the timer directly calls your function (a callback) then it will fire re-enterently. If the timer posts a message which is then dispatched the calls will be serialized.

    2) If you are usijng a callback with a timer there are four approaches.
    2a - Use a guard block. Prevents re-entrency but misses "ticks"
    2b - Design your callback to be re-entrant
    2c - Have your callback implement some type of queuing mechanism
    2d - Ignore the issue and have an unstable program.

    I try to avoid approach "2d"
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: non-period timer

    Quote Originally Posted by danandu
    We know that the timer is regularly ticking at a fixed time (say 1ms)

    Call the thread in the timer function.

    But restrict this by using a flag setting.

    Check this flag for every tick (1ms) inside the timer event.

    if the flag, says the thread is over, then call the thread again!.

    Eureka! you can still execute your function without worrying about timer ticks and without losing any function.

    --Dan
    Instead of using a timer for the clock tick, you may consider using a thread that uses WaitForSingleObject(..., nTimeout ). When the WFSO times out, it can set an event to wake the other threads. You may wonder why I'm so down on timers. Well, the reason is that when you use a timer, the messages that the OS sends for timers share the same message queue as other UI messages. What this means is that user input can interrupt the sending of the timer messages. If the UI is busy processing other messages, your timer message won't get through. I figure that since the timer is being used to retrieve data not directly related to the UI, why not completely decouple the retrieval of data from UI operations?

    For that reason instead of using the timer, just spin up a 'timer' thread that uses WFSO because WFSO is never impacted by the UI (or a hung UI).

  14. #14
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: non-period timer

    Quote Originally Posted by TheCPUWizard
    1) As to the re-entrncy, it depends on the type of timer. If the timer directly calls your function (a callback) then it will fire re-enterently. If the timer posts a message which is then dispatched the calls will be serialized.
    Ah, so I wasn't going crazy afterall (well, not for this reason anyway). Thanks for the clarification.

  15. #15
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: non-period timer

    Arjay,

    WFSO is a valid alternate approach. But I do want to point out that multiple threads can each have their own message pump and avoid the interference you are talking about....
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured