Пример #1
0
        public bool Remove(TCompletion continuation)
        {
            if (Interlocked.CompareExchange(ref single, null, continuation) == continuation)
            {
                return(true);
            }

            if (completed != null)
            {
                return(completed.Remove(continuation));
            }

            return(false);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }