IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Waiting For Elapsed Time, TickCount vs. DateTime

Tuesday 29 June, 2004, 10:13 AM

Sometimes, code needs to do some stuff for a certain amount of time and then stop. I won't list all the reasons, but it's a common enough requirement.

There are many approaches to this. Sometimes, setting a timer to go off is an appropriate solution. However, there are costs involved with this - timers consume resource, and may result in thread switches. On the other hand, they're a whole lot cheaper than busy waiting. So unless you're creating a staggering number of timers, they're probably a good bet.

But sometimes, it's convenient to test for expiration of a timer in a loop. It's still possible to use a timer object in this case, but you have to make it set a boolean, and test that boolean. It's not actually all that convenient, and if you're already looping around for other reasons, timers may not be the best bet.

So a while ago, I wrote a little helper class that has this usage model:

WaitForTicks wait = new WaitForTicks(TimeSpan.FromSeconds(5));
while (!wait.TimeIsUp)
{
    // Do Work...
}

Internally, this class uses Environment.TickCount internally. The tick count is the only reliable way of doing this sort of waiting. Using DateTime and TimeSpan is arguably simpler, but doesn't work if the system clock gets changed half way through a wait operation. Because Environment.TickCount increases monotonically, it is immune to system clock changes.

The only problem is that it spends about 25 out of every 50 days negative, and wraps round every 50 days. This is because the tick count is a 32 bit integer, and it counts milliseconds - that's roughly how often such a count wraps. It's pretty easy to go wrong. For example, I wrote some code that uses the Indy socket library to retrieve some email, but it crashes if you use it on a day when the tick count is negative. (This is a bug in the Indy library. They appear to wrap the tick count in a variable which doesn't permit negative numbers. Although to be fair, there was a bug in the docs for TickCount for ages, which said incorrectly that it wraps from Int32.MaxValue back down to zero, and never goes negative. That's not true, and it would actually be really inconvenient if it were true.)

So I wrote a little helper class to wrap this stuff up, and deal reliably with wrap around. It's described in more detail here, or you can just go straight to the source code.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk