-
March 23rd, 2007, 11:34 PM
#1
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?
-
March 24th, 2007, 12:19 AM
#2
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
-
March 24th, 2007, 12:26 AM
#3
Re: non-period timer
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.
-
March 24th, 2007, 12:46 AM
#4
Re: non-period timer
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
-
March 24th, 2007, 12:48 AM
#5
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
-
March 24th, 2007, 01:07 AM
#6
Re: non-period timer
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;
}
-
March 24th, 2007, 01:09 AM
#7
Re: non-period timer
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?
-
March 24th, 2007, 01:19 AM
#8
Re: non-period timer
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 ?
-
March 24th, 2007, 02:29 AM
#9
Re: non-period timer
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
-
March 24th, 2007, 03:21 AM
#10
Re: non-period timer
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.
-
March 24th, 2007, 08:36 AM
#11
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
-
March 24th, 2007, 08:54 AM
#12
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
-
March 24th, 2007, 04:51 PM
#13
Re: non-period timer
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).
-
March 24th, 2007, 04:52 PM
#14
Re: non-period timer
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.
-
March 24th, 2007, 05:01 PM
#15
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
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|