public bool Remove(TCompletion continuation) { if (Interlocked.CompareExchange(ref single, null, continuation) == continuation) { return(true); } if (completed != null) { return(completed.Remove(continuation)); } return(false); }
public bool Remove(TCompletion continuation) { TCompletion temp = single; if (temp != null && temp == continuation) { single = null; return(true); } if (completed != null) { return(completed.Remove(continuation)); } return(false); }
public Task <bool> WaitAsync(Int32 duration, CancellationToken token) { VerboseLog("{0:000}|{1}|async wait requested", Thread.CurrentThread.Id, _id); CheckDisposed(); token.ThrowIfCancellationRequested(); if (_sem.TryAcquire()) { VerboseLog("{0:000}|{1}|async wait immediate success", Thread.CurrentThread.Id, _id); return(Task.FromResult(true)); } if (duration == 0) { return(Task.FromResult(false)); } if (_asyncWaiters == null) { lock (this) { if (_asyncWaiters == null) { _asyncWaiters = new ConcurrentLinkedQueue <AsyncWaiter>(); } } } AsyncWaiter waiter = new AsyncWaiter(); TaskCompletionSource <bool> task = new TaskCompletionSource <bool>(); waiter.Task = task; if (duration != -1) { waiter.CancelDelay = new CancellationTokenSource(); waiter.Delay = Task.Delay(duration, waiter.CancelDelay.Token); waiter.Delay.ContinueWith(new ActionContinuation(() => TimeoutAsync(waiter))); } if (token != CancellationToken.None) { waiter.CancelRegistration = token.Register(() => CancelAsync(waiter)); } _asyncWaiters.Add(waiter); VerboseLog("{0:000}|{1}|async wait enqued: {2:X}; {3}", Thread.CurrentThread.Id, _id, waiter.GetHashCode(), waiter.Task.Task.Id); if (_wasDisposed || token.IsCancellationRequested || waiter.Delay != null && waiter.Delay.IsCompleted) { // Mitigate the above race where a finishing condition occured // before where able to add our waiter to the waiters list. if (_asyncWaiters.Remove(waiter)) { CleanUpWaiter(waiter); } } return(task.Task); }