using System;
/// <summary>
/// Provides a way of testing for whether a certain amount of time has
/// elapsed.
/// </summary>
/// <remarks>
/// <p>This is intended for use in loops which need to do some work until
/// a specific amount of time has elapsed. For example, it can be used
/// to test if a timeout has occurred yet. It can also be used in simple
/// benchmark tests to see how many operations can be performed in a
/// given amount of time.</p>
///
/// <p>Its usage is:</p>
/// <code>
/// WaitForTicks wait = new WaitForTicks(TimeSpan.FromSeconds(2));
/// while (!wait.TimeIsUp)
/// {
/// ... do work ...
/// }
/// </code>
///
/// <p>This uses the <see cref="Environment.TickCount"/>, which increases
/// monotonically, so it will be unperturbed by changes to the system
/// time. This class deals correctly with wrapping around, both when the
/// tick count rolls from positive to negative, and when it rolls around
/// through 0. However, because the tick count is a 32 bit number, this
/// class cannot wait for more than <see cref="Int32.MaxValue"/>
/// milliseconds.</p>
/// </remarks>
public class WaitForTicks
{
private readonly int startTicks;
private readonly uint maxTicks;
/// <summary>
/// Create a WaitForTicks object initialized to expire in the
/// specified amount of time.
/// </summary>
/// <param name="time">The amount of time into the future in
/// which this timer's <see cref="TimeIsUp"/> property will
/// return true.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if
/// the specified time is more than <see cref="Int32.MaxValue"/>
/// millseconds in the future.</exception>
public WaitForTicks(TimeSpan time)
{
double fullMaxTicks = time.TotalMilliseconds;
if (fullMaxTicks > int.MaxValue)
{
// The int.MaxValue limit is a bit arbitrary. In practice,
// the limit will depend on how often code checks the
// TimeIsUp property. Here, they have another
// int.MaxValue seconds to check it. (They have to
// check it before the difference rolls round.)
// You could narrow the margin. For example,
// testing for fullMaxTicks > uint.MaxValue - 10000
// would be OK if you were testing the value at least
// once every 10 seconds.
// With the code as it is, there's a safety margin of
// some 24.5 days!
throw new ArgumentOutOfRangeException("time", time,
"Cannot wait for more than Int32.MaxValue milliseconds");
}
maxTicks = (uint) fullMaxTicks;
startTicks = Environment.TickCount;
}
/// <summary>
/// Returns true if the amount of time specified at construction has
/// elapsed since construction.
/// </summary>
public bool TimeIsUp
{
get
{
uint diff = (uint) (Environment.TickCount - startTicks);
return diff >= maxTicks;
}
}
}
Copyright © 2002-2003, Interact Software Ltd. Please direct
all Web site inquiries to webmaster@interact-sw.co.uk