views:

1193

answers:

5

Does the absolute value protect the following code from the Environment.TickCount wrap?


If Math.Abs((Environment.TickCount And Int32.MaxValue) - StartTime) > Interval Then
  StartTime = (Environment.TickCount And Int32.MaxValue) 
  .
  .
  .
End If

Is there a better method of guarding against the Environment.TickCount() wrap?

(This is .NET 1.1.)

Edit - Modified code according to Microsoft Environment.TickCount help.

+1  A: 

I'm not sure what you're trying to accomplish. It looks like you are trying to detect if a particular interval has occured and if so execute some specific logic.

This is likely to cause you no end of pain if you use Environment.TickCount for this purpose. As you pointed out this value can and will wrap roughly every 25 days. There is no way to prevent this from happening and if you try to you'll end up with bugs in your code.

Instead why not do the following:

  • Use an actual Timer for the internal and execution of the event
  • Store the StartTime as a DateTime (or just Date in VB) value. This value has a much longer range. It's highly unlikely that your app will run long enough for this value to wrap around(OS will need a reboot long before then :) ).
JaredPar
A: 

Depending on your accuracy, why don't you just use:

DateTime.Now.Ticks

There's no wrapping for this Ticks.

Keltex
A: 

Your code will most likely not work. If the app was to run on Vista or a newer Windows version, one could use GetTickCount64, but I assume that this is not the case, given that you use .NET 1.1.

Your code should not check for equality with the interval, as this will likely go wrong. Use a Int64 to store the ticks, store the last processed tick in a variable, and if this variable is greater than the new tick value you've got a wrap and need to increment your total tick base (the Int64) - assuming that you check the tick more often than 1 every 12 days... ;)

Lucero
+1  A: 

Avoiding the wrapping problem is easy, provided that the time span you want to measure is no less than 24.8 days (anything longer can't be represented in a signed integer). In C#:

int start = Environment.TickCount;
DoLongRunningOperation();
int elapsedTime = Environment.TickCount - start;

I am not very familiar with VB.NET, but as long as you use unchecked math, this will work and you don't have to worry about the wrap.

For example, if Environment.TickCount wraps from 2147483600 to -2147483596, it doesn't matter. You can still compute the difference between them, which is 100 milliseconds.

Qwertie
A: 

Just use the stopwatch:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;

It will return an int64 and not an int32. Plus it's easier to understand.

Carra