System.Environment.TickCount wrapping

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

The documentation for TickCount states quite plainly that it wraps from its
max value of Int32.MaxValue to zero at the wraparound point (approx. every
24.9 days). I did build a longer term timer based on this assumption, but
when a long term test of the product stopped working at ~25 days, and I
attached a debugging session of VS to the app, I could have sworn that I saw
TickCount return a large negative value. Unfortunately, VS locked soon after,
brought the app down with it, and the machine was rebooted. I don't have any
other machines around here that have been running for > 25 days to further
test the observation.

So the question is: does TickCount wrap to Int32.MinValue (and the
documentation is wrong) or to 0 (and I was mistaken in my observation) ?

Thanks
Lionel
 
Brock:
Thanks - so the documentation IS wrong - TickCount does wrap to
Int32.MinValue and not 0.

Lionel
 
I have always thought that the System.Environment.TickCount property was
written late on a Friday afternoon when the writer was gagging for a beer. I
cannot understand why they didn't return it as an Int64 (Long) - Then it
would have matched the 'adjusted' documentation.

Obviously, it P/Invokes the GetTickCount API which returns a DWORD, so what
is happening when the value gets close to and 'passes' Int32.MaxValue is,
(remember that the Hex values represent a DWORD or Unsigned Integer):

&H7FFFFFFD
&H7FFFFFFE
&H7FFFFFFF <-- Int32.MaxValue (Approx 24.85 days)
&H80000000 <-- Int32.MinValue
&H80000001
&H80000002

As you can see, a simple increment is what appears the wrap around from
Int32.MaxValue to Int32.MinValue.

After approx 49.7 days, the following happens:

&HFFFFFFFD
&HFFFFFFFE
&HFFFFFFFF <-- -1
&H00000000 <-- 0
&H00000001
&H00000002

The wrap around from &HFFFFFFFF to &H00000000 is handled by simply ignoring
the overflow.

One option, if one is concerned about the 2nd half of the roll-around
period, is to promote the result from an Int32 to an Int64. A bit of magic
is required to make it convert properly but it does not appear to have any
significant performanse impact. Try the following:

Dim _x As Integer
Dim _y As Integer
Dim _z As Long

_x = System.Environment.TickCount

_z = CType("&H" & System.Environment.TickCount.ToString("X"), Int64)

_y = System.Environment.TickCount

Console.WriteLine(_x)

Console.WriteLine(_z)

Console.WriteLine(_y)

On my slowest machine, this code produces the same value for _x, _y, and _z
when System.Environment.TickCount is positive. I'll have to wait a few days
to see what it does when it's 'negative'.

I have seen a number of programmers rely on TickCount and GetTickCount to
indicate how long the machine has been up. This is OK only if the machine
has been up for less than approx 49.7 days. If it has been up longer than
one has to remember that TickCount and GetTickCount represent the number of
milliseconds elapsed since the system was started OR the number of
milliseconds elapsed since the counter rolled around to 0, whichever
happened more recently. A very important point but one that is easy to
overlook.
 
Back
Top