private async Task <IDisposable> CancellableTaskAsync(TaskCompletionSource <IDisposable> tcs, CancellationToken cancellationToken) { IDisposable disposable; using (cancellationToken.Register((Action)(() => { bool lockTaken = false; object obj; bool flag; try { Monitor.Enter(obj = this._lock, ref lockTaken); this.CheckInvariant(); flag = QueueExtensions.Remove <TaskCompletionSource <IDisposable> >(this._pending, tcs); } finally { if (lockTaken) { Monitor.Exit(obj); } } if (!flag) { return; } Task task = TaskEx.Run((Action)(() => tcs.TrySetCanceled())); TaskCollector.Default.Add(task, "AsyncLock Propagate cancel"); }))) disposable = await tcs.Task.ConfigureAwait(false); return(disposable); }
private void RemoveWork(object workObject) { AsyncFifoWorker.WorkHandle workHandle = (AsyncFifoWorker.WorkHandle)workObject; bool lockTaken = false; object obj; try { Monitor.Enter(obj = this._lock, ref lockTaken); if (!QueueExtensions.Remove <AsyncFifoWorker.WorkHandle>(this._workQueue, workHandle)) { return; } } finally { if (lockTaken) { Monitor.Exit(obj); } } workHandle.Dispose(); }
public Task <TItem> AllocateAsync(CancellationToken cancellationToken) { bool lockTaken = false; Queue <TItem> queue; try { Monitor.Enter((object)(queue = this._pool), ref lockTaken); if (this._pool.Count > 0) { TItem obj = this._pool.Dequeue(); Debug.Assert(!EqualityComparer <TItem> .Default.Equals(default(TItem), obj)); return(TaskEx.FromResult <TItem>(obj)); } if (this._allocationCount >= this._poolSize) { CancellationTaskCompletionSource <TItem> completionSource = new CancellationTaskCompletionSource <TItem>((Action <CancellationTaskCompletionSource <TItem> >)(wh => QueueExtensions.Remove <CancellationTaskCompletionSource <TItem> >(this._waiters, wh)), cancellationToken); this._waiters.Enqueue(completionSource); return(completionSource.Task); } ++this._allocationCount; } finally { if (lockTaken) { Monitor.Exit((object)queue); } } TItem instance = Activator.CreateInstance <TItem>(); this._allocationTracker.Add(instance); return(TaskEx.FromResult <TItem>(instance)); }