Results 1 to 19 of 19

Thread: Do not use Timers incorrectly

  1. #1

    Thread Starter
    Banned randem's Avatar
    Join Date
    Oct 2002
    Location
    Maui, Hawaii
    Posts
    11,385

    Do not use Timers incorrectly

    Many people are having problems with timers and asking about timers. If you want to use a timer in your app. Please follow these suggestion to help insure that you do not have problems.

    1) In VB6, Do not Disable and Re-Enable your timer. This will cause your timer to still run after the program is terminated causing the timer function to still run (unless you disable the timer in your unload code).

    Upon entering the timer code use

    VB Code:
    1. Private Sub Timer1_Timer()
    2.  
    3. 'Add your code here
    4.  
    5. End Sub
    2) You can use more than one timer on a form.

    Seperate your code into each timer that will interrupt on it own interval. Timers should not be confused with timing functions. A timer will interrupt your code on the set intervals so that you may do other things. Timing functions are called to time the elapsed time between set areas in code or time betwwen events happening.

    Following these rules will make sure that your problems are not timer issues.
    Last edited by randem; May 9th, 2005 at 04:13 PM.

  2. #2
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: Do not use Timers incorrectly

    Nice thing randem!
    I'll like to add
    3) Check whether you need a timer at all or not
    Timers run in seperate thread. Your code continues to run after enabling the timer. Usually u want to just wait for the timer to finish and then resume your code. In such cases just use loops with DoEvents instead of timers.

  3. #3
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Do not use Timers incorrectly

    You could even go as far as saying, don't use Timers at all. Using GetTickCount is better, and QueryPerformanceCounter is even better. Try for those

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  4. #4

    Thread Starter
    Banned randem's Avatar
    Join Date
    Oct 2002
    Location
    Maui, Hawaii
    Posts
    11,385

    Re: Do not use Timers incorrectly

    chemicalNova,

    Timers are essential. You can't interrupt running code with GetTickCount. That is the main purpose of timers... To interrupt running code.

    You are confusing Timers with Timing.
    Last edited by randem; May 9th, 2005 at 04:19 AM.

  5. #5
    Hyperactive Member hassa046's Avatar
    Join Date
    May 2001
    Location
    Venlo, The Netherlands
    Posts
    336

    Re: Do not use Timers incorrectly

    Nice post. Very helpful.
    Better to regret things you did, than those you didn't
    International Intelligence

  6. #6
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Do not use Timers incorrectly

    Quote Originally Posted by randem
    VB Code:
    1. Private Sub Timer1_Timer()
    2. Timer1.Enabled = False
    3.  
    4. 'Add your code here
    5.  
    6.     Select Case tmrflg
    7.  
    8.         Case (First Condition)
    9.  
    10.         Case (Second Condition)
    11.  
    12.         ....
    13.  
    14.     End Select
    15.  
    16. 'and just before exiting the timer code do
    17.  
    18. Timer1.Enabled = True
    19. End Sub
    Shouldn't it be?:

    VB Code:
    1. Timer1.Enabled = False
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  7. #7
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    I really don't understand what's the fuss about timers...

    I have an application with about 30 forms, some of the forms have multiple instances while app is running, and ALL forms have at least one timer on each form... have not had ANY problem with the app as of yet regarding timers. Memory is fine, CPU usage is low, I really don't understand why you guys have a problem with timers.

    And by the way, this:
    VB Code:
    1. Private Sub Timer1_Timer()
    2. Timer1.Enabled = False
    3.  
    4. 'Add your code here
    5.  
    6. 'and just before exiting the timer code do
    7. Timer1.Enabled = True
    8. End Sub
    NEVER HAPENS to interrupt itself !! Did you actually try it ?

    A timer never fires again until you exit the current instance... so what's the point of that code ?

  8. #8
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Do not use Timers incorrectly

    You should never be using Timers to begin with unless you are that desperate on low CPU usage. Timers are slow, inaccurate, and inconsistant. It's even worse on XP computers since they go 10 times faster, making them really inaccurate and inconsistant. And you are right. It's even more worse when having two or more timers run at the same time. Using managed loops with a frame limiter is the way to go for better accuracy. And that loop should be the only loop in your app that'll take care of everything, such as a Game Loop. But that would mean more CPU usage.

  9. #9
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    Anyone wants to prove me wrong with actual proof (code) ??
    I know the timer is inacurate, so prove me wrong on other things that you think it's bad about timers...

    I'm curious on why everybody is so disapointed about the timer control, cuz I never had any problems with it in my 8 years of programming in VB.

  10. #10
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    First of all, a timer does NOT interrupt (this is not C++ to use interrupts), and the following code proves it !
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long
    4. Private LastTick As Long
    5.  
    6. Private Sub Form_Load()
    7.     LastTick = GetTickCount
    8.     Timer1.Interval = 500
    9. End Sub
    10.  
    11. Private Sub Timer1_Timer()
    12.     Debug.Print "Timer1_Timer: " & GetTickCount - LastTick
    13.     LastTick = GetTickCount
    14.    
    15.     Pause 1 ' pause for one second
    16. End Sub
    17.  
    18. Private Sub Pause(ByVal Interval As Single)
    19.     Dim EndTime As Single
    20.     EndTime = Timer + Interval
    21.    
    22.     Do
    23.         DoEvents
    24.     Loop Until Timer >= EndTime
    25. End Sub

    Output:
    Timer1_Timer: 500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    keeps going like this...

    What does this prove ?
    First of all, if a timer would really Interrupt, then you would get an event EVERY 500 ms, and guess what ? it does not...

    This proves that the interval you set in a timer is the time it takes from the time the timer sub ends to the time the sub get's called again. The time spent inside the call is added to the total time (timer's Interval), THEREFORE everyone thinks that a timer is not precise !! and guess what, if you add the 500 ms with the 1 second you will have a total of 1500 ms, from what I see the timer interval takes exactly 1500... hmmm what a coincidence !

    It seems that a timer is more precise than I originaly thought...

  11. #11

    Thread Starter
    Banned randem's Avatar
    Join Date
    Oct 2002
    Location
    Maui, Hawaii
    Posts
    11,385

    Re: Do not use Timers incorrectly

    CVMichael,

    You are indeed correct. MS must have changed the timers.

  12. #12
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    Thank you... I feel much better now

    Any other bad things about timers ?

    I can't wait until this "myth" of "timers = bad" ends.

  13. #13
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    That's weird , I thought there was another post between post number 9 and 10... hmmm....

  14. #14
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Do not use Timers incorrectly

    When using Timers in XP, they are 10 times faster than usual. And GetTickCount is not as accurate. It's only 10 ms accurate. Best to use the QueryPerformanceCounter And the QuerePerformanceFrequency API's for 1 ms accuracy.

  15. #15
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    Hmmm, same code as above, but on my home computer, I get this output:

    Timer1_Timer: 501
    Timer1_Timer: 1502
    Timer1_Timer: 1502
    Timer1_Timer: 1502
    Timer1_Timer: 1503
    Timer1_Timer: 1502

    It seems that a timer is more acurate on some comptuers than others...

  16. #16
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    I'm just curious what output do you guys get when you run the following function:
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long
    4.  
    5. Private Sub Form_Load()
    6.     FindTimeAccuracy
    7. End Sub
    8.  
    9. Private Sub FindTimeAccuracy()
    10.     Dim SmallestDiff As Single, PrevTime As Single, CurrTime As Single, K As Long
    11.     Dim CurrTick As Long, PrevTick As Long
    12.    
    13.     PrevTime = Timer
    14.     SmallestDiff = 2 ^ 16
    15.    
    16.     For K = 0 To 1000000
    17.         CurrTime = Timer
    18.        
    19.         If PrevTime <> CurrTime Then
    20.             If CurrTime - PrevTime < SmallestDiff Then SmallestDiff = CurrTime - PrevTime
    21.            
    22.             PrevTime = Timer
    23.         End If
    24.     Next K
    25.    
    26.     Debug.Print "Timer = " & SmallestDiff * 1000 & " ms"
    27.    
    28.     PrevTick = GetTickCount
    29.     SmallestDiff = 2 ^ 16
    30.    
    31.     For K = 0 To 10000000
    32.         CurrTick = GetTickCount
    33.        
    34.         If PrevTick <> CurrTick Then
    35.             If CurrTick - PrevTick < SmallestDiff Then SmallestDiff = CurrTick - PrevTick
    36.            
    37.             PrevTick = GetTickCount
    38.         End If
    39.     Next K
    40.    
    41.     Debug.Print "GetTickCount = " & SmallestDiff & " ms"
    42. End Sub
    I get this output:

    Timer = 15.625 ms
    GetTickCount = 15 ms

    What do you get ?

  17. #17
    New Member
    Join Date
    May 2005
    Posts
    1

    Re: Do not use Timers incorrectly

    Quote Originally Posted by CVMichael
    First of all, a timer does NOT interrupt (this is not C++ to use interrupts), and the following code proves it !
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long
    4. Private LastTick As Long
    5.  
    6. Private Sub Form_Load()
    7.     LastTick = GetTickCount
    8.     Timer1.Interval = 500
    9. End Sub
    10.  
    11. Private Sub Timer1_Timer()
    12.     Debug.Print "Timer1_Timer: " & GetTickCount - LastTick
    13.     LastTick = GetTickCount
    14.    
    15.     Pause 1 ' pause for one second
    16. End Sub
    17.  
    18. Private Sub Pause(ByVal Interval As Single)
    19.     Dim EndTime As Single
    20.     EndTime = Timer + Interval
    21.    
    22.     Do
    23.         DoEvents
    24.     Loop Until Timer >= EndTime
    25. End Sub

    Output:
    Timer1_Timer: 500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    Timer1_Timer: 1500
    keeps going like this...

    What does this prove ?
    First of all, if a timer would really Interrupt, then you would get an event EVERY 500 ms, and guess what ? it does not...

    This proves that the interval you set in a timer is the time it takes from the time the timer sub ends to the time the sub get's called again. The time spent inside the call is added to the total time (timer's Interval), THEREFORE everyone thinks that a timer is not precise !! and guess what, if you add the 500 ms with the 1 second you will have a total of 1500 ms, from what I see the timer interval takes exactly 1500... hmmm what a coincidence !

    It seems that a timer is more precise than I originaly thought...
    Yes you are right! BUT!!! Try bigger or lower values for timer interval. For example - if 10 then relust is:

    Timer1_Timer: 16
    Timer1_Timer: 1016
    Timer1_Timer: 1015
    Timer1_Timer: 1016
    Timer1_Timer: 1015

    and go on...
    My CPU is AMD 3000 + with 512 MB RAM


  18. #18
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Do not use Timers incorrectly

    I already knew that the timer is not precise. The point I was trying to make is that the timer does not Interrupt. Randem deleted the post where he was stating that timers interrupt... now I look like an fool because of that... He also edited his first post. Now this thread is kinda poitless because there is no good proof for "Do not use Timers incorrectly".


    Edit: Edited post language - Hack
    Last edited by Hack; May 24th, 2005 at 06:40 PM.

  19. #19
    Frenzied Member thegreatone's Avatar
    Join Date
    Aug 2003
    Location
    Oslo, Norway. Mhz:4800 x12
    Posts
    1,333

    Re: Do not use Timers incorrectly

    Quote Originally Posted by CVMichael
    I'm just curious what output do you guys get when you run the following function:
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long
    4.  
    5. Private Sub Form_Load()
    6.     FindTimeAccuracy
    7. End Sub
    8.  
    9. Private Sub FindTimeAccuracy()
    10.     Dim SmallestDiff As Single, PrevTime As Single, CurrTime As Single, K As Long
    11.     Dim CurrTick As Long, PrevTick As Long
    12.    
    13.     PrevTime = Timer
    14.     SmallestDiff = 2 ^ 16
    15.    
    16.     For K = 0 To 1000000
    17.         CurrTime = Timer
    18.        
    19.         If PrevTime <> CurrTime Then
    20.             If CurrTime - PrevTime < SmallestDiff Then SmallestDiff = CurrTime - PrevTime
    21.            
    22.             PrevTime = Timer
    23.         End If
    24.     Next K
    25.    
    26.     Debug.Print "Timer = " & SmallestDiff * 1000 & " ms"
    27.    
    28.     PrevTick = GetTickCount
    29.     SmallestDiff = 2 ^ 16
    30.    
    31.     For K = 0 To 10000000
    32.         CurrTick = GetTickCount
    33.        
    34.         If PrevTick <> CurrTick Then
    35.             If CurrTick - PrevTick < SmallestDiff Then SmallestDiff = CurrTick - PrevTick
    36.            
    37.             PrevTick = GetTickCount
    38.         End If
    39.     Next K
    40.    
    41.     Debug.Print "GetTickCount = " & SmallestDiff & " ms"
    42. End Sub
    I get this output:

    Timer = 15.625 ms
    GetTickCount = 15 ms

    What do you get ?
    I also get

    Timer = 15.625 ms
    GetTickCount = 15 ms
    Zeegnahtuer?

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