[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

VB6 Timer Object not working as expected

Posted on 2007-08-01
9
Medium Priority
?
2,010 Views
Last Modified: 2013-12-20
guaranteed to Stump the expert.

I am using the timer object in VB6.  Along with that I am using the GetTickCount api.  I call the GetTickCount at the beginning of the timer routine and display the returned value, we'll call it INTERVAL.  I call it again at the end of the routine and display the delta from the first call (the elapsed time of the routine called ELAPSED).  I set the timer interval so that it is larger than the elapsed time of the routine.  When I run this code the INTERVAL is always the sum of ELAPSED and the timer interval.  This implies that the timer object restarts itself after every execution of the timer routine.  I don't know exactly how the timer object works, but this result was HIGHLY unexpected.  What I expected was that as long as ELPASED was less than the timer interval then INTERVAL would be very close to the timer interval.  But that is not the case.  Can you explain this?  Is this a bug?  Or is this "By Design"?  
0
Comment
Question by:tkamrath
9 Comments
 
LVL 12

Expert Comment

by:jkaios
ID: 19613245
The DateDiff() function is more accurate in calculating ELAPSE times than the Timer object/function as it gets reset to 0 at 12:00 midnight.

Here is a sample method to calculate the time elapsed between two time intervals:

'===========================================================
Dim StartTime
Dim EndTime
Dim Duration
Dim ii As Long

StartTime = Now()

Do Until ii >= 1234567
   DoEvents
   ii = ii + 1
Loop

EndTime = Now()

Duration = DateDiff("s", StartTime, EndTime)

MsgBox "It took " & Duration & " seconds to finish the job."
'===========================================================
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 19613756
Can you show us your code please?....
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 19613908
Don't quite inderstand what you have found, but, yes, the Timer keeps on running, firing its timer event every time its interval is reached.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 38

Expert Comment

by:PaulHews
ID: 19614602
I also see the same behaviour you are describing.  It's as if the timer stops timing while executing the code in the timer event.

It is an interesting discovery, and I think probably by design, although I can't find anything in any documentation anywhere.  It's probably to prevent the re-entrancy problems that would occur if the timer fired every 100 ms when the code takes 400 ms to execute.  Combined with a DoEvents statement in the timer event code, and you would have an event cascade, leading to a stack overflow.

It seems to me that in the past VB versions (3, 4, or 5)  I have experienced re-entrancy problems with timers, but with this behaviour, I don't see how that's possible anymore.
0
 
LVL 38

Accepted Solution

by:
PaulHews earned 1000 total points
ID: 19614773
Here's the code I used if anyone wants to play with it.  Two buttons, a text box and a timer.  Compile for most consistent results.

Option Explicit
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Private mInterval As Long

Private Sub Command1_Click()
    Me.Cls
    Timer1.Interval = CLng(Text1.Text)
    Timer1.Enabled = True
End Sub

Private Sub Command2_Click()
    Timer1.Enabled = False
    mInterval = 0
End Sub

Private Sub Form_Load()
    Text1.Text = "250"
    Me.AutoRedraw = True
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Timer1.Enabled = False
End Sub

Private Sub Timer1_Timer()
    If Not Me.Enabled Then Exit Sub
   
    Dim lngElapsed As Long, lngIntervalOld As Long
    Dim i As Long, j As Long
   
    lngIntervalOld = mInterval
    mInterval = GetTickCount
   
    For i = 1 To 100000
        DoEvents
    Next
   
   
    lngElapsed = GetTickCount - mInterval
    If lngIntervalOld > 0 And mInterval > 0 Then
        Me.Print mInterval - lngIntervalOld, lngElapsed
    End If
   
End Sub
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 19616118
I think I now understand what behaviour you find surprising.

That is that the Timer countdown does not proceed while the object's Timer event is still being processed. As far as I remember that has always been the case.
0
 

Author Comment

by:tkamrath
ID: 19616272
This is all good.  It means I am not imagining things.  SOMEONE ELSE SEES IT!!!

But if most people don't know this, think of all the screwed up code out there.  If I have an app where I need execution every 100 msec and my routine takes 42 msec to execute, that is about a 50% error.  Most people probably write that off thinking the VB timer is just not that accurate.  BUT...

If your timer interval is 1000 msec and you set the timer interval to TIMER1.Interval = 1000 - ELAPSEDTIME at the end of the timer routine then the timer is VERY accurate.  Now that I know I am not imagining it, that is how I will fix this.
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 19616304
I always restart the timer at the end of the Timer event. I even disable it first

Sub Timer1_Timer()

  ' do the event processing

   Timer1.Enabled = False
   Timer1.Interval = 100
   Timer1.Enabled = True
End Sub
0
 
LVL 13

Expert Comment

by:Mark_FreeSoftware
ID: 19627743

so, what you did GrahamSkan, was what the timer internal was already doing :)
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question