| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.Runtime
- {
- using System;
- using System.Threading;
- struct TimeoutHelper
- {
- DateTime deadline;
- bool deadlineSet;
- TimeSpan originalTimeout;
- public static readonly TimeSpan MaxWait = TimeSpan.FromMilliseconds(Int32.MaxValue);
- public TimeoutHelper(TimeSpan timeout)
- {
- Fx.Assert(timeout >= TimeSpan.Zero, "timeout must be non-negative");
- this.originalTimeout = timeout;
- this.deadline = DateTime.MaxValue;
- this.deadlineSet = (timeout == TimeSpan.MaxValue);
- }
- public TimeSpan OriginalTimeout
- {
- get { return this.originalTimeout; }
- }
- public static bool IsTooLarge(TimeSpan timeout)
- {
- return (timeout > TimeoutHelper.MaxWait) && (timeout != TimeSpan.MaxValue);
- }
- public static TimeSpan FromMilliseconds(int milliseconds)
- {
- if (milliseconds == Timeout.Infinite)
- {
- return TimeSpan.MaxValue;
- }
- else
- {
- return TimeSpan.FromMilliseconds(milliseconds);
- }
- }
- public static int ToMilliseconds(TimeSpan timeout)
- {
- if (timeout == TimeSpan.MaxValue)
- {
- return Timeout.Infinite;
- }
- else
- {
- long ticks = Ticks.FromTimeSpan(timeout);
- if (ticks / TimeSpan.TicksPerMillisecond > int.MaxValue)
- {
- return int.MaxValue;
- }
- return Ticks.ToMilliseconds(ticks);
- }
- }
- public static TimeSpan Min(TimeSpan val1, TimeSpan val2)
- {
- if (val1 > val2)
- {
- return val2;
- }
- else
- {
- return val1;
- }
- }
- public static TimeSpan Add(TimeSpan timeout1, TimeSpan timeout2)
- {
- return Ticks.ToTimeSpan(Ticks.Add(Ticks.FromTimeSpan(timeout1), Ticks.FromTimeSpan(timeout2)));
- }
- public static DateTime Add(DateTime time, TimeSpan timeout)
- {
- if (timeout >= TimeSpan.Zero && DateTime.MaxValue - time <= timeout)
- {
- return DateTime.MaxValue;
- }
- if (timeout <= TimeSpan.Zero && DateTime.MinValue - time >= timeout)
- {
- return DateTime.MinValue;
- }
- return time + timeout;
- }
- public static DateTime Subtract(DateTime time, TimeSpan timeout)
- {
- return Add(time, TimeSpan.Zero - timeout);
- }
- public static TimeSpan Divide(TimeSpan timeout, int factor)
- {
- if (timeout == TimeSpan.MaxValue)
- {
- return TimeSpan.MaxValue;
- }
- return Ticks.ToTimeSpan((Ticks.FromTimeSpan(timeout) / factor) + 1);
- }
- public TimeSpan RemainingTime()
- {
- if (!this.deadlineSet)
- {
- this.SetDeadline();
- return this.originalTimeout;
- }
- else if (this.deadline == DateTime.MaxValue)
- {
- return TimeSpan.MaxValue;
- }
- else
- {
- TimeSpan remaining = this.deadline - DateTime.UtcNow;
- if (remaining <= TimeSpan.Zero)
- {
- return TimeSpan.Zero;
- }
- else
- {
- return remaining;
- }
- }
- }
- public TimeSpan ElapsedTime()
- {
- return this.originalTimeout - this.RemainingTime();
- }
- void SetDeadline()
- {
- Fx.Assert(!deadlineSet, "TimeoutHelper deadline set twice.");
- this.deadline = DateTime.UtcNow + this.originalTimeout;
- this.deadlineSet = true;
- }
- public static void ThrowIfNegativeArgument(TimeSpan timeout)
- {
- ThrowIfNegativeArgument(timeout, "timeout");
- }
- public static void ThrowIfNegativeArgument(TimeSpan timeout, string argumentName)
- {
- if (timeout < TimeSpan.Zero)
- {
- throw Fx.Exception.ArgumentOutOfRange(argumentName, timeout, InternalSR.TimeoutMustBeNonNegative(argumentName, timeout));
- }
- }
- public static void ThrowIfNonPositiveArgument(TimeSpan timeout)
- {
- ThrowIfNonPositiveArgument(timeout, "timeout");
- }
- public static void ThrowIfNonPositiveArgument(TimeSpan timeout, string argumentName)
- {
- if (timeout <= TimeSpan.Zero)
- {
- throw Fx.Exception.ArgumentOutOfRange(argumentName, timeout, InternalSR.TimeoutMustBePositive(argumentName, timeout));
- }
- }
- [Fx.Tag.Blocking]
- public static bool WaitOne(WaitHandle waitHandle, TimeSpan timeout)
- {
- ThrowIfNegativeArgument(timeout);
- if (timeout == TimeSpan.MaxValue)
- {
- waitHandle.WaitOne();
- return true;
- }
- else
- {
- return waitHandle.WaitOne(timeout, false);
- }
- }
- }
- }
|