Пример #1
0
        public async Task WaitAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            var spinner = new SpinWait();

            while (true)
            {
                var capturedCounter = Interlocked.CompareExchange(ref counter, 0, 0);
                var nextCounter     = capturedCounter - 1;
                if (Interlocked.CompareExchange(ref counter, nextCounter, capturedCounter) == capturedCounter)
                {
                    if (capturedCounter > 0)
                    {
                        return;
                    }
                    else
                    {
                        var latch       = new AsyncLatch();
                        var waitContext = new WaitContext {
                            Latch = latch
                        };
                        try {
                            waitContexts.Enqueue(waitContext);
                            await latch.WaitAsync(cancellationToken).ConfigureAwait(false);

                            return;
                        } catch (OperationCanceledException e) {
                            if (ResolveWaitContextUndoAsync(waitContext))
                            {
                                throw;
                            }
                            else
                            {
                                await waitContext.Latch.WaitAsync(CancellationToken.None).ConfigureAwait(false);

                                return;
                            }
                            //                     return ResolveWaitContextUndoAsync(waitContext, e);
                        }
                    }
                }
                spinner.SpinOnce();
            }
        }
Пример #2
0
        public Task WaitAsync(CancellationToken token = default(CancellationToken))
        {
            var spinner = new SpinWait();

            while (!token.IsCancellationRequested)
            {
                var previousValue = Interlocked.CompareExchange(ref state, kStateNeutral, kStateSet);
                if (previousValue == kStateSet)
                {
                    return(Task.FromResult(false));
                }
                var nextValue = previousValue + 1;
                if (Interlocked.CompareExchange(ref state, nextValue, previousValue) == previousValue)
                {
                    var latch = new AsyncLatch();
                    latches.Enqueue(latch);
                    return(latch.WaitAsync(token));
                }
                spinner.SpinOnce();
            }
            token.ThrowIfCancellationRequested();
            // impossible code
            throw new InvalidStateException();
        }