Offers common timeout support. The source was extracted from the System.Threading.ReaderWriterLockSlim class.
public struct TimeoutTracker
{
private readonly int _total;
private readonly int _start;
public bool IsExpired
{
get
{
return RemainingMilliseconds == 0;
}
}
public int RemainingMilliseconds
{
get
{
if (_total == -1 || _total == 0)
{
return _total;
}
int tickCount = Environment.TickCount - _start;
if (tickCount < 0 || tickCount >= _total)
{
return 0;
}
return _total - tickCount;
}
}
public TimeoutTracker(TimeSpan timeout)
{
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > 2147483647)
{
throw new ArgumentOutOfRangeException("timeout");
}
_total = (int)totalMilliseconds;
if (_total != -1 && _total != 0)
{
_start = Environment.TickCount;
return;
}
_start = 0;
}
public TimeoutTracker(int millisecondsTimeout)
{
if (millisecondsTimeout < -1)
{
throw new ArgumentOutOfRangeException("millisecondsTimeout");
}
_total = millisecondsTimeout;
if (_total != -1 && _total != 0)
{
_start = Environment.TickCount;
return;
}
_start = 0;
}
}
// =================================================================
// Usage:
// =================================================================
void Main()
{
var tt = new TimeoutTracker(1000);
Thread.Sleep(500);
if (tt.IsExpired)
{
Console.WriteLine("Timeout expired.");
}
else
{
Console.WriteLine("Still ticking with \"{0}\" milli-seconds left on the clock...",
tt.RemainingMilliseconds);
}
Thread.Sleep(500);
if (tt.IsExpired)
{
Console.WriteLine("Timeout expired.");
}
else
{
Console.WriteLine("Still ticking with \"{0}\" milli-seconds left on the clock...",
tt.RemainingMilliseconds);
}
}