예제 #1
0
 protected virtual void Dispose(bool disposing)
 {
     if (this.disposed)
     {
         return;
     }
     if (disposing)
     {
         lock (this.syncObj)
         {
             while (this.pending.Count > 0)
             {
                 AsyncResultWaiter <int> asyncResultWaiter = this.pending.Dequeue();
                 if (!asyncResultWaiter.StillPending)
                 {
                     continue;
                 }
                 this.pendingWaitersToExpire.Remove(asyncResultWaiter);
                 ThreadPool.QueueUserWorkItem((object o) => ((AsyncResult <int>)o).Complete(new TimeoutException("The asynchronous semaphore was disposed."), false), asyncResultWaiter.AsyncResult);
             }
             if (this.timer != null)
             {
                 this.timer.Dispose();
                 this.timer = null;
             }
         }
     }
     this.disposed = true;
 }
예제 #2
0
        private void TimeoutExpiredWaiters(object state)
        {
            DateTime dateTime = DateTime.UtcNow.Add(AsyncSemaphore.FutureExpiryThreshold);
            List <AsyncResultWaiter <int> > asyncResultWaiters = new List <AsyncResultWaiter <int> >(1);

            lock (this.syncObj)
            {
                while (this.pendingWaitersToExpire.Count > 0)
                {
                    AsyncResultWaiter <int> asyncResultWaiter = this.First <AsyncResultWaiter <int> >(this.pendingWaitersToExpire.Keys);
                    if (asyncResultWaiter.ExpiryTime >= dateTime)
                    {
                        TimeSpan zero = asyncResultWaiter.ExpiryTime.Subtract(DateTime.UtcNow);
                        if (zero < TimeSpan.Zero)
                        {
                            zero = TimeSpan.Zero;
                        }
                        this.timer.Change(zero, TimeSpan.FromMilliseconds(-1));
                        break;
                    }
                    else
                    {
                        asyncResultWaiters.Add(asyncResultWaiter);
                        this.pendingWaitersToExpire.Remove(asyncResultWaiter);
                        asyncResultWaiter.StillPending = false;
                        this.numExpiredWaitersInQueue++;
                    }
                }
            }
            foreach (AsyncResultWaiter <int> asyncResultWaiter1 in asyncResultWaiters)
            {
                ThreadPool.QueueUserWorkItem((object delegateState) => ((AsyncResult <int>)delegateState).Complete(new TimeoutException("The resource(s) could not be acquired within the specified timeout period."), false), asyncResultWaiter1.AsyncResult);
            }
        }
예제 #3
0
        protected void TimeoutExpiredWaiters(object state_ignored)
        {
            DateTime dateTime = DateTime.UtcNow.Add(AsyncSignal <SignalDataType> .FutureExpiryThreshold);
            List <AsyncResultWaiter <SignalDataType> > asyncResultWaiters = new List <AsyncResultWaiter <SignalDataType> >(1);

            lock (this.syncObj)
            {
                while (this.waiters.Count > 0)
                {
                    AsyncResultWaiter <SignalDataType> item = this.waiters.Keys[0];
                    if (item.ExpiryTime >= dateTime)
                    {
                        TimeSpan zero = item.ExpiryTime.Subtract(DateTime.UtcNow);
                        if (zero < TimeSpan.Zero)
                        {
                            zero = TimeSpan.Zero;
                        }
                        this.timer.Change(zero, TimeSpan.FromMilliseconds(-1));
                        break;
                    }
                    else
                    {
                        asyncResultWaiters.Add(item);
                        this.waiters.RemoveAt(0);
                    }
                }
            }
            foreach (AsyncResultWaiter <SignalDataType> asyncResultWaiter in asyncResultWaiters)
            {
                ThreadPool.QueueUserWorkItem((object state) => ((AsyncResult <SignalDataType>)state).Complete(new TimeoutException("The asynchronous signal was not set within the specified timeout period."), false), asyncResultWaiter.AsyncResult);
            }
        }
예제 #4
0
        public int Compare(AsyncResultWaiter <T> x, AsyncResultWaiter <T> y)
        {
            int num = x.ExpiryTime.CompareTo(y.ExpiryTime);

            if (num == 0)
            {
                num = x.WaiterIndex.CompareTo(y.WaiterIndex);
            }
            return(num);
        }
예제 #5
0
        private void CleanupExpiredWaiters(object syncObj)
        {
            Queue <AsyncResultWaiter <int> > asyncResultWaiters = new Queue <AsyncResultWaiter <int> >();

            while (this.pending.Count > 0)
            {
                AsyncResultWaiter <int> asyncResultWaiter = this.pending.Dequeue();
                if (!asyncResultWaiter.StillPending)
                {
                    continue;
                }
                asyncResultWaiters.Enqueue(asyncResultWaiter);
            }
            this.pending = asyncResultWaiters;
            this.numExpiredWaitersInQueue = 0;
        }
예제 #6
0
 public void Release(int releaseCount)
 {
     this.CheckDisposed();
     if (releaseCount < 1)
     {
         throw new ArgumentOutOfRangeException("releaseCount", (object)releaseCount, "releaseCount must be >= 1");
     }
     lock (this.syncObj)
     {
         if (releaseCount > this.maxCount - this.count)
         {
             throw new SemaphoreFullException();
         }
         this.count += releaseCount;
         while (this.pending.Count > 0)
         {
             AsyncResultWaiter <int> asyncResultWaiter = this.pending.Peek();
             if (asyncResultWaiter.StillPending)
             {
                 if (asyncResultWaiter.AsyncResult.ResultData > this.count)
                 {
                     break;
                 }
                 this.pending.Dequeue();
                 this.count -= asyncResultWaiter.AsyncResult.ResultData;
                 if (asyncResultWaiter.ExpiryTime != DateTime.MaxValue)
                 {
                     this.pendingWaitersToExpire.Remove(asyncResultWaiter);
                 }
                 ThreadPool.QueueUserWorkItem((object o) => ((AsyncResult <int>)o).Complete(null, false), asyncResultWaiter.AsyncResult);
             }
             else
             {
                 this.pending.Dequeue();
                 this.numExpiredWaitersInQueue--;
             }
         }
     }
 }
예제 #7
0
        public IAsyncResult BeginAcquire(int acquireCount, TimeSpan timeout, AsyncCallback callback, object state)
        {
            IAsyncResult asyncResult;

            this.CheckDisposed();
            if (acquireCount <= 0 || acquireCount > this.maxCount)
            {
                throw new ArgumentOutOfRangeException("acquireCount", (object)acquireCount, "acquireCount must be > 0 and <= MaxCount");
            }
            if (timeout < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("timeout", (object)timeout, "must be >= 0");
            }
            AsyncResult <int> asyncResult1 = new AsyncResult <int>("AsyncSemaphore.Acquire", callback, state)
            {
                ResultData = acquireCount
            };

            if (timeout == TimeSpan.Zero)
            {
                asyncResult1.Complete(new TimeoutException("The resource(s) could not be acquired within the specified timeout period."), true);
                return(asyncResult1);
            }
            DateTime dateTime = (timeout == TimeSpan.MaxValue ? DateTime.MaxValue : DateTime.UtcNow.Add(timeout));

            lock (this.syncObj)
            {
                if (acquireCount > this.count || this.pending.Count > 0)
                {
                    if (this.maxPending.HasValue && this.pending.Count == this.maxPending.Value)
                    {
                        if (this.numExpiredWaitersInQueue <= 0)
                        {
                            asyncResult1.Complete(new SemaphoreQueueExhaustedException("Too many pending waiters"), true);
                            asyncResult = asyncResult1;
                            return(asyncResult);
                        }
                        else
                        {
                            this.CleanupExpiredWaiters(this.syncObj);
                        }
                    }
                    AsyncSemaphore asyncSemaphore = this;
                    int            num            = asyncSemaphore.waiterIndex;
                    int            num1           = num;
                    asyncSemaphore.waiterIndex = num + 1;
                    AsyncResultWaiter <int> asyncResultWaiter = new AsyncResultWaiter <int>(asyncResult1, dateTime, num1);
                    this.pending.Enqueue(asyncResultWaiter);
                    if (timeout != TimeSpan.MaxValue)
                    {
                        this.pendingWaitersToExpire.Add(asyncResultWaiter, new NoResults());
                        if (this.timer == null)
                        {
                            this.timer = new Timer(new TimerCallback(this.TimeoutExpiredWaiters), null, timeout, TimeSpan.FromMilliseconds(-1));
                        }
                        else if (asyncResultWaiter.AsyncResult == this.First <AsyncResultWaiter <int> >(this.pendingWaitersToExpire.Keys).AsyncResult)
                        {
                            this.timer.Change(timeout, TimeSpan.FromMilliseconds(-1));
                        }
                    }
                }
                else
                {
                    this.count -= acquireCount;
                    asyncResult1.Complete(null, true);
                }
                return(asyncResult1);
            }
            return(asyncResult);
        }