コード例 #1
0
        public void Next_throws_if_disposed()
        {
            var sequence = new CancellationTokenSequence();

            sequence.Dispose();

            Assert.Throws <OperationCanceledException>(() => sequence.Next());
        }
コード例 #2
0
        public void Dispose_is_idempotent()
        {
            var sequence = new CancellationTokenSequence();

            sequence.Next();

            sequence.Dispose();
            sequence.Dispose();
            sequence.Dispose();
            sequence.Dispose();
        }
コード例 #3
0
        public void Dispose_cancels_previous_token()
        {
            var sequence = new CancellationTokenSequence();

            var token = sequence.Next();

            Assert.False(token.IsCancellationRequested);

            sequence.Dispose();

            Assert.True(token.IsCancellationRequested);
        }
コード例 #4
0
        public void Cancel_is_idempotent()
        {
            var sequence = new CancellationTokenSequence();

            var token = sequence.Next();

            Assert.False(token.IsCancellationRequested);

            sequence.CancelCurrent();
            sequence.CancelCurrent();
            sequence.CancelCurrent();
            sequence.CancelCurrent();
        }
コード例 #5
0
        public void Next_cancels_previous_token()
        {
            var sequence = new CancellationTokenSequence();

            var token1 = sequence.Next();

            Assert.False(token1.IsCancellationRequested);

            var token2 = sequence.Next();

            Assert.True(token1.IsCancellationRequested);
            Assert.False(token2.IsCancellationRequested);
        }
コード例 #6
0
        public void Cancel_does_not_throw_if_no_token_yet_issued()
        {
            var sequence = new CancellationTokenSequence();

            sequence.CancelCurrent();
        }
コード例 #7
0
        public async Task Concurrent_callers_to_Next_only_result_in_one_non_cancelled_token_being_issued()
        {
            const int loopCount = 10000;

            var logicalProcessorCount = Environment.ProcessorCount;
            var threadCount           = Math.Max(2, logicalProcessorCount);

            using var sequence  = new CancellationTokenSequence();
            using var barrier   = new Barrier(threadCount);
            using var countdown = new CountdownEvent(loopCount * threadCount);
            var completedCount = 0;

            var completionTokenSource = new CancellationTokenSource();
            var completionToken       = completionTokenSource.Token;
            var winnerByIndex         = new int[threadCount];

            var tasks = Enumerable
                        .Range(0, threadCount)
                        .Select(i => Task.Run(() => ThreadMethod(i)))
                        .ToList();

            Assert.True(
                countdown.Wait(TimeSpan.FromSeconds(10)),
                "Test should have completed within a reasonable amount of time");

            await Task.WhenAll(tasks);

            Assert.AreEqual(loopCount, completedCount);

            await Console.Out.WriteLineAsync("Winner by index: " + string.Join(",", winnerByIndex));

            // Assume hyper threading, so halve logical processors (could use WMI or P/Invoke for more robust answer)
            if (logicalProcessorCount <= 2)
            {
                Assert.Inconclusive("This test requires more than one physical processor to run.");
            }

            return;

            void ThreadMethod(int i)
            {
                while (true)
                {
                    barrier.SignalAndWait();

                    if (completionToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var token = sequence.Next();

                    barrier.SignalAndWait();

                    if (!token.IsCancellationRequested)
                    {
                        Interlocked.Increment(ref completedCount);
                        Interlocked.Increment(ref winnerByIndex[i]);
                    }

                    if (countdown.Signal())
                    {
                        completionTokenSource.Cancel();
                    }
                }
            }
        }
コード例 #8
0
        public void Dispose_does_not_throw_if_no_token_yet_issued()
        {
            var sequence = new CancellationTokenSequence();

            sequence.Dispose();
        }