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; }
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); } }
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); } }
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); }
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; }
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--; } } } }
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); }