TimeoutHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / TimeoutHelper.cs / 1 / TimeoutHelper.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel 
{
    using System; 
    using System.Threading; 
    using System.ServiceModel.Channels;
 
    struct TimeoutHelper
    {
        internal static TimeSpan DefaultBufferTime { get { return TimeSpan.FromMilliseconds(150); } }
        internal static TimeSpan Infinite { get { return TimeSpan.MaxValue; } } 
        internal static TimeSpan MaxWait = TimeSpan.FromMilliseconds(Int32.MaxValue);
 
        DateTime deadline; 
        bool deadlineSet;
 
        TimeSpan originalTimeout;

        internal void SetDeadline()
        { 
            DiagnosticUtility.DebugAssert(!deadlineSet, "TimeoutHelper deadline set twice.");
            this.deadline = DateTime.UtcNow + this.originalTimeout; 
            this.deadlineSet = true; 
        }
 
        internal TimeoutHelper(TimeSpan timeout)
        {
            if (timeout < TimeSpan.Zero)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
            } 
 
            if (IsTooLarge(timeout))
            { 
                timeout = MaxWait;
            }

            this.originalTimeout = timeout; 
            this.deadline = DateTime.MaxValue;
            this.deadlineSet = (timeout == TimeSpan.MaxValue); 
        } 

        public TimeSpan OriginalTimeout 
        {
            get { return this.originalTimeout; }
        }
 
        static public bool IsTooLarge(TimeSpan timeout)
        { 
            return (timeout > MaxWait) && (timeout != Infinite); 
        }
 
        public TimeSpan MinRemainingTime(TimeSpan otherTimeout)
        {
            TimeSpan myTimeout = this.RemainingTime();
            if (myTimeout < otherTimeout) 
            {
                return myTimeout; 
            } 
            else
            { 
                return otherTimeout;
            }
        }
 
        public TimeSpan MinRemainingTime(TimeoutHelper other)
        { 
            if (!this.deadlineSet) 
            {
                this.SetDeadline(); 
            }
            if (!other.deadlineSet)
            {
                other.SetDeadline(); 
            }
 
            if (this.deadline < other.deadline) 
            {
                return this.RemainingTime(); 
            }
            else
            {
                return other.RemainingTime(); 
            }
        } 
 
        public TimeSpan RemainingTime()
        { 
            return this.RemainingTimeExpireZero();
        }

        public TimeSpan RemainingTimeExpireZero() 
        {
            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 RemainingTimeExpireNegative()
        {
            if (!this.deadlineSet) 
            {
                this.SetDeadline(); 
                return this.originalTimeout; 
            }
            else if (this.deadline == DateTime.MaxValue) 
            {
                return TimeSpan.MaxValue;
            }
            else 
            {
                return this.deadline - DateTime.UtcNow; 
            } 
        }
 
        public TimeSpan ElapsedTime()
        {
            return this.originalTimeout - this.RemainingTimeExpireZero();
        } 

        public static TimeSpan ReserveTimeAtEnd(TimeSpan timeout) 
        { 
            return ReserveTimeAtEnd(timeout, DefaultBufferTime);
        } 

        public static TimeSpan ReserveTimeAtEnd(TimeSpan timeout, TimeSpan bufferTime)
        {
            DiagnosticUtility.DebugAssert(bufferTime >= TimeSpan.Zero, "Negative bufferTime passed to ReserveTimeAtEnd."); 

            if (timeout < TimeSpan.Zero) 
            { 
                return TimeSpan.Zero;
            } 
            if (timeout >= Add(bufferTime, bufferTime))
            {
                return Add(timeout, TimeSpan.Zero - bufferTime);
            } 
            return Ticks.ToTimeSpan((Ticks.FromTimeSpan(timeout) / 2) + 1);
        } 
 
        public static TimeSpan FromMilliseconds(int milliseconds)
        { 
            if (milliseconds == Timeout.Infinite)
            {
                return TimeSpan.MaxValue;
            } 
            else
            { 
                return TimeSpan.FromMilliseconds(milliseconds); 
            }
        } 

        public static TimeSpan FromMilliseconds(uint milliseconds)
        {
            if (milliseconds == unchecked((uint) 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 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 static bool WaitOne(WaitHandle waitHandle, TimeSpan timeout, bool exitSync)
        {
            if (timeout == TimeSpan.MaxValue)
            { 
                waitHandle.WaitOne();
                return true; 
            } 
            else
            { 
                if (IsTooLarge(timeout))
                {
                    timeout = MaxWait;
                } 

                return waitHandle.WaitOne(timeout, exitSync); 
            } 
        }
    } 

    sealed class BackoffTimeoutHelper
    {
        readonly static int maxSkewMilliseconds = (int) (IOThreadTimer.SystemTimeResolutionTicks / TimeSpan.TicksPerMillisecond); 
        readonly static long maxDriftTicks = IOThreadTimer.SystemTimeResolutionTicks * 2;
        readonly static TimeSpan defaultInitialWaitTime = TimeSpan.FromMilliseconds(1); 
        readonly static TimeSpan defaultMaxWaitTime = TimeSpan.FromMinutes(1); 

        DateTime deadline; 
        TimeSpan maxWaitTime;
        TimeSpan waitTime;
        IOThreadTimer backoffTimer;
        WaitCallback backoffCallback; 
        object backoffState;
        Random random; 
        TimeSpan originalTimeout; 

        internal BackoffTimeoutHelper(TimeSpan timeout) 
            : this(timeout, BackoffTimeoutHelper.defaultMaxWaitTime)
        {
        }
 
        internal BackoffTimeoutHelper(TimeSpan timeout, TimeSpan maxWaitTime)
            : this(timeout, maxWaitTime, BackoffTimeoutHelper.defaultInitialWaitTime) 
        { 
        }
 
        internal BackoffTimeoutHelper(TimeSpan timeout, TimeSpan maxWaitTime, TimeSpan initialWaitTime)
        {
            this.random = new Random(GetHashCode());
            this.maxWaitTime = maxWaitTime; 
            this.originalTimeout = timeout;
            Reset(timeout, initialWaitTime); 
        } 

        public TimeSpan OriginalTimeout 
        {
            get
            {
                return this.originalTimeout; 
            }
        } 
 
        void Reset(TimeSpan timeout, TimeSpan initialWaitTime)
        { 
            if (timeout == TimeSpan.MaxValue)
            {
                this.deadline = DateTime.MaxValue;
            } 
            else
            { 
                this.deadline = DateTime.UtcNow + timeout; 
            }
            this.waitTime = initialWaitTime; 
        }

        public bool IsExpired()
        { 
            if (this.deadline == DateTime.MaxValue)
            { 
                return false; 
            }
            else 
            {
                return (DateTime.UtcNow >= this.deadline);
            }
        } 

        public void WaitAndBackoff(WaitCallback callback, object state) 
        { 
            if (this.backoffCallback != callback || this.backoffState != state)
            { 
                if (this.backoffTimer != null)
                {
                    this.backoffTimer.Cancel();
                } 
                this.backoffCallback = callback;
                this.backoffState = state; 
                this.backoffTimer = new IOThreadTimer(callback, state, false, BackoffTimeoutHelper.maxSkewMilliseconds); 
            }
 
            TimeSpan backoffTime = WaitTimeWithDrift();
            Backoff();
            this.backoffTimer.Set(backoffTime);
        } 

        public void WaitAndBackoff() 
        { 
            Thread.Sleep(WaitTimeWithDrift());
            Backoff(); 
        }

        TimeSpan WaitTimeWithDrift()
        { 
            return Ticks.ToTimeSpan(Math.Max(
                Ticks.FromTimeSpan(BackoffTimeoutHelper.defaultInitialWaitTime), 
                Ticks.Add(Ticks.FromTimeSpan(this.waitTime), 
                    (long) (uint) this.random.Next() % (2 * BackoffTimeoutHelper.maxDriftTicks + 1) - BackoffTimeoutHelper.maxDriftTicks)));
        } 

        void Backoff()
        {
            if (waitTime.Ticks >= (maxWaitTime.Ticks / 2)) 
            {
                waitTime = maxWaitTime; 
            } 
            else
            { 
                waitTime = TimeSpan.FromTicks(waitTime.Ticks * 2);
            }

            if (this.deadline != DateTime.MaxValue) 
            {
                TimeSpan remainingTime = this.deadline - DateTime.UtcNow; 
                if (this.waitTime > remainingTime) 
                {
                    this.waitTime = remainingTime; 
                    if (this.waitTime < TimeSpan.Zero)
                    {
                        this.waitTime = TimeSpan.Zero;
                    } 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK