コード例 #1
0
        public void WaitAsync_NotEmpty_CanCedeTurn()
        {
            using (var cts = new CancellationTokenSource())
                using (var turnstile = new Turnstile())
                {
                    var t1 = turnstile.WaitAsync();
                    var t2 = turnstile.WaitAsync(cts.Token);
                    var t3 = turnstile.WaitAsync();

                    Assert.That(turnstile.HasWaiting);

                    TaskAssert.DoesNotEnd(t1);
                    TaskAssert.DoesNotEnd(t2);
                    TaskAssert.DoesNotEnd(t3);

                    cts.Cancel();
                    Assert.That(turnstile.Turn());

                    TaskAssert.Completed(t1);
                    TaskAssert.Cancelled(t2);
                    TaskAssert.DoesNotEnd(t3);

                    Assert.That(turnstile.Turn());

                    TaskAssert.Completed(t3);

                    Assert.That(!turnstile.HasWaiting);
                    Assert.That(!turnstile.Turn());
                }
        }
コード例 #2
0
        public void WaitAsync_NotEmpty_WaitsForTurn()
        {
            using (var turnstile = new Turnstile())
            {
                var t1 = turnstile.WaitAsync();
                var t2 = turnstile.WaitAsync();
                var t3 = turnstile.WaitAsync();

                Assert.That(turnstile.HasWaiting);

                TaskAssert.DoesNotEnd(t1);
                TaskAssert.DoesNotEnd(t2);
                TaskAssert.DoesNotEnd(t3);

                Assert.That(turnstile.Turn());

                TaskAssert.Completed(t1);
                TaskAssert.DoesNotEnd(t2);
                TaskAssert.DoesNotEnd(t3);

                Assert.That(turnstile.Turn());

                TaskAssert.Completed(t2);
                TaskAssert.DoesNotEnd(t3);

                Assert.That(turnstile.Turn());

                TaskAssert.Completed(t3);

                Assert.That(!turnstile.HasWaiting);
                Assert.That(!turnstile.Turn());
            }
        }
コード例 #3
0
        public void Dispose_FaultsAwaiters()
        {
            var turnstile = new Turnstile();

            using (var cts = new CancellationTokenSource())
            {
                var awaiters = new[]
                {
                    turnstile.WaitAsync(),
                    turnstile.WaitAsync(cts.Token),
                    turnstile.WaitAsync(),
                    turnstile.WaitAsync()
                };

                cts.Cancel();
                turnstile.Dispose();

                TaskAssert.Faulted <ObjectDisposedException>(awaiters[0]);
                TaskAssert.Cancelled(awaiters[1]);

                foreach (var awaiter in awaiters.Skip(2))
                {
                    TaskAssert.Faulted <ObjectDisposedException>(awaiter);
                }
            }
        }
コード例 #4
0
ファイル: Quota.cs プロジェクト: KFAFSP/Whetstone.Core
        /// <inheritdoc />
        /// <exception cref="OperationCanceledException">
        /// <paramref name="ACancel"/> was canceled.
        /// </exception>
        /// <exception cref="ObjectDisposedException">This instance is disposed.</exception>
        public async Task <SynchronizationHandle> WaitAsync(CancellationToken ACancel)
        {
            ThrowIfDisposed();
            ACancel.ThrowIfCancellationRequested();

            // Decrement the balance.
            if (Interlocked.Decrement(ref FBalance) < 0)
            {
                // Reservation was made, await our turn.
                try
                {
                    await FWaiting.WaitAsync(ACancel);
                }
                catch (OperationCanceledException)
                {
                    // Waiting was canceled.
                    // Increment the balance again to release the reservation.
                    // NOTE: Reference is never null.
                    // ReSharper disable once ExceptionNotDocumented
                    Interlocked.Increment(ref FBalance);
                    throw;
                }
            }

            // Enter the section.
            // NOTE: Reference is never null.
            // ReSharper disable once ExceptionNotDocumented
            Interlocked.Increment(ref FActive);
            return(new Handle(this));
        }
コード例 #5
0
        public void WaitAsync_Disposed_ThrowsObjectDisposedException()
        {
            var turnstile = new Turnstile();

            turnstile.Dispose();

            TaskAssert.Faulted <ObjectDisposedException>(turnstile.WaitAsync());
        }
コード例 #6
0
        public void HasWaiting_DetectsCeded()
        {
            using (var cts = new CancellationTokenSource())
                using (var turnstile = new Turnstile())
                {
                    var awaiter = turnstile.WaitAsync(cts.Token);

                    TaskAssert.DoesNotEnd(awaiter);
                    Assert.That(turnstile.HasWaiting);

                    cts.Cancel();

                    TaskAssert.Cancelled(awaiter);
                    Assert.That(!turnstile.HasWaiting);
                }
        }