public void TryEnqueueAfterComplete()
 {
     var queue = new AsyncQueue<int>();
     Assert.True(queue.TryEnqueue(42));
     queue.Complete();
     Assert.False(queue.TryEnqueue(42));
 }
Пример #2
0
        public async Task StressTest()
        {
            var queue = new AsyncQueue <int>();
            var list  = new List <int>();

            var task = Task.Run(async() =>
            {
                await foreach (var i in queue)
                {
                    list.Add(i);
                }
            });

            var writerCount = 10;
            var writers     = new Task[writerCount];
            var indexes     = new int[writerCount];
            var writing     = true;
            var paused      = false;

            for (var i = 0; i < writerCount; i++)
            {
                var n = i;
                writers[n] = Task.Run(async() =>
                {
                    while (writing)
                    {
                        if (!paused && queue.TryWrite(indexes[n]))
                        {
                            indexes[n]++;
                        }

                        await Task.Delay(RandomProvider.Random.Next(100));
                    }
                });
            }

            await Task.Delay(2000);

            paused = true;
            await Task.Delay(1000);

            paused = false;
            await Task.Delay(2000);

            writing = false;
            queue.Complete();
            await task;

            await Task.WhenAll(writers);

            var total = 0;

            for (var i = 0; i < writerCount; i++)
            {
                Console.WriteLine($"{i}: {indexes[i]}");
                total += indexes[i];
            }

            Assert.That(list.Count, Is.EqualTo(total));
        }
Пример #3
0
        public void EnqueueAfterComplete()
        {
            var queue = new AsyncQueue <int>();

            queue.Complete();
            Assert.Throws <InvalidOperationException>(() => queue.Enqueue(42));
        }
Пример #4
0
        public async Task DequeueManyThenComplete()
        {
            var queue = new AsyncQueue <int>();
            var list  = new List <Task <int> >();

            for (var i = 0; i < 4; i++)
            {
                list.Add(queue.DequeueAsync());
            }

            queue.Complete();
            foreach (var task in list)
            {
                var threw = false;
                try
                {
                    await task.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    threw = true;
                }

                Assert.True(threw);
            }
        }
Пример #5
0
    public void DequeueCancellationAndCompletionStress()
    {
        var queue = new AsyncQueue <GenericParameterHelper>();

        queue.Complete();

        // This scenario was proven to cause a deadlock before a bug was fixed.
        // This scenario should remain to protect against regressions.
        int iterations = 0;
        var stopwatch  = Stopwatch.StartNew();

        while (stopwatch.ElapsedMilliseconds < TestTimeout / 2)
        {
            var cts = new CancellationTokenSource();
            using (var barrier = new Barrier(2))
            {
                var otherThread = Task.Run(delegate
                {
                    Assert.True(barrier.SignalAndWait(TestTimeout));
                    queue.DequeueAsync(cts.Token);
                    Assert.True(barrier.SignalAndWait(TestTimeout));
                });

                Assert.True(barrier.SignalAndWait(TestTimeout));
                cts.Cancel();
                Assert.True(barrier.SignalAndWait(TestTimeout));

                Assert.True(otherThread.Wait(TestTimeout));
            }

            iterations++;
        }

        this.Logger.WriteLine("Iterations: {0}", iterations);
    }
Пример #6
0
        public void EndListening()
        {
            if (!IsListening)
            {
                throw new InvalidOperationException();
            }

            Debug.Assert(_cancellationTokenSource is object);
            Debug.Assert(_queue is object);
            Debug.Assert(_listenTasks is object);

            try
            {
                // Even though the Tasks created to run the compilation servers can never throw,
                // the CancellationToken from this source ends up getting passed throughout the
                // named pipe infrastructure. Parts of that infrastructure hook into
                // CancellationToken.Register and those will throw during a Cancel operation.
                //
                // Most notably of these is IOCancellationHelper.Cancel. This has a race where it
                // will try to cancel IO on a disposed SafeHandle. That causes an ObjectDisposedException
                // to propagate out from the Cancel method here.
                //
                // There is no good way to guard against this hence we just have to accept it as a
                // possible outcome.
                _cancellationTokenSource.Cancel();
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, $"Cancelling server listens threw an exception");
            }

            try
            {
                Task.WaitAll(_listenTasks);
            }
            catch (Exception ex)
            {
                Logger.LogException(
                    ex,
                    $"Listen tasks threw exception during {nameof(EndListening)}"
                    );
            }

            _queue.Complete();
            _queue.WhenCompletedTask.Wait();

            // Anything left in the AsyncQueue after completion will not be handled by the client
            // and must be cleaned up by the host.
            while (_queue.TryDequeue(out var connectionResult))
            {
                connectionResult.NamedPipeClientConnection?.Dispose();
            }

            _queue = null;
            _cancellationTokenSource.Dispose();
            _cancellationTokenSource = null;
            _listenTasks             = null;
            IsListening = false;
        }
Пример #7
0
        public void TryEnqueueAfterComplete()
        {
            var queue = new AsyncQueue <int>();

            Assert.True(queue.TryEnqueue(42));
            queue.Complete();
            Assert.False(queue.TryEnqueue(42));
        }
Пример #8
0
        public async Task WaitingCompletedQueueIsFalse()
        {
            var queue = new AsyncQueue <int>();

            queue.Complete();

            Assert.That(await queue.WaitAsync(), Is.False);
        }
Пример #9
0
        public void WritingCompletedQueueIsFalse()
        {
            var queue = new AsyncQueue <int>();

            queue.Complete();

            Assert.That(queue.TryWrite(1), Is.False);
        }
Пример #10
0
        public async Task CompletingQueueEndsWait()
        {
            var queue = new AsyncQueue <int>();

            var task = Task.Run(async() => await queue.WaitAsync());

            queue.Complete();

            Assert.That(await task, Is.False);
        }
Пример #11
0
 public void UnusedQueueGCPressure()
 {
     this.CheckGCPressure(
         delegate
     {
         var queue = new AsyncQueue <GenericParameterHelper>();
         queue.Complete();
         Assert.True(queue.IsCompleted);
     },
         maxBytesAllocated: 81);
 }
Пример #12
0
        public async Task TryDequeueAfterComplete()
        {
            var queue = new AsyncQueue <int>();

            queue.Enqueue(13);
            queue.Complete();
            await queue.WhenCompletedTask.ConfigureAwait(false);

            int value;

            Assert.True(queue.TryDequeue(out value));
            Assert.Equal(13, value);
        }
Пример #13
0
        private void DrainQueue()
        {
            // Tell the queue not to accept any more items
            _queue.Complete();

            // Spin through the queue and pass in our cancelled token, so that the waiting tasks are cancelled.
            // NOTE: This only really works because the first thing that CallbackAsync does is check for cancellation
            // but generics make it annoying to store the TaskCompletionSource<TResult> on the QueueItem so this
            // is the best we can do for now. Ideally we would manipulate the TaskCompletionSource directly here
            // and just call SetCanceled
            while (_queue.TryDequeue(out var item))
            {
                _ = item.CallbackAsync(default, new CancellationToken(true));
Пример #14
0
        /// <inheritdoc />
        public async ValueTask DisposeAsync()
        {
            // note: DisposeAsync should not throw (CA1065)

            if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 1)
            {
                return;
            }

            _connections.Complete();
            _cancel.Cancel();
            await _terminating.CfAwaitCanceled();

            _cancel.Dispose();
        }
Пример #15
0
 public void UnusedQueueGCPressure()
 {
     if (this.ExecuteInIsolation())
     {
         this.CheckGCPressure(
             delegate
         {
             var queue = new AsyncQueue <GenericParameterHelper>();
             queue.Complete();
             Assert.True(queue.IsCompleted);
         },
             maxBytesAllocated: 81,
             allowedAttempts: 30);
     }
 }
        public async Task DequeueThenComplete()
        {
            var queue = new AsyncQueue<int>();
            var task = queue.DequeueAsync();
            Assert.False(task.IsCompleted);

            queue.Complete();
            var threw = false;
            try
            {
                await task.ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                threw = true;
            }

            Assert.True(threw);
        }
Пример #17
0
        public async Task DequeueThenComplete()
        {
            var queue = new AsyncQueue <int>();
            var task  = queue.DequeueAsync();

            Assert.False(task.IsCompleted);

            queue.Complete();
            var threw = false;

            try
            {
                await task.ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                threw = true;
            }

            Assert.True(threw);
        }
Пример #18
0
        public async Task DequeueAfterCompleteWithData()
        {
            var queue = new AsyncQueue <int>();

            queue.Enqueue(42);
            queue.Complete();
            await queue.WhenCompletedTask.ConfigureAwait(false);

            Assert.Equal(42, await queue.DequeueAsync().ConfigureAwait(false));

            var threw = false;

            try
            {
                await queue.DequeueAsync().ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                threw = true;
            }
            Assert.True(threw);
        }
Пример #19
0
        public async Task Enumerate()
        {
            var queue = new AsyncQueue <int>();
            var list  = new List <int>();

            var task = Task.Run(async() =>
            {
                await foreach (var i in queue)
                {
                    list.Add(i);
                }
            });

            for (var i = 0; i < 100; i++)
            {
                Assert.That(queue.TryWrite(i), Is.True);
            }

            queue.Complete();
            await task;

            Assert.That(list.Count, Is.EqualTo(100));
        }
Пример #20
0
        public async Task TaskCompletesAsyncWithComplete()
        {
            var queue = new AsyncQueue <int>();

            var tcs  = new TaskCompletionSource <bool>();
            var task = queue.DequeueAsync().ContinueWith(
                t =>
            {
                tcs.Task.Wait();
                return(0);
            },
                default(CancellationToken),
                TaskContinuationOptions.ExecuteSynchronously,
                TaskScheduler.Default);

            queue.Complete();
            Assert.False(queue.WhenCompletedTask.IsCompleted);
            tcs.SetResult(true);
            await queue.WhenCompletedTask.ConfigureAwait(false);

            // The AsyncQueue<T>.Task property won't complete until all of the
            // existing DequeueAsync values have also completed.
            Assert.True(task.IsCompleted);
        }
        public async Task DequeueManyThenComplete()
        {
            var queue = new AsyncQueue<int>();
            var list = new List<Task<int>>();
            for (var i = 0; i < 4; i++)
            {
                list.Add(queue.DequeueAsync());
            }

            queue.Complete();
            foreach (var task in list)
            {
                var threw = false;
                try
                {
                    await task.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    threw = true;
                }

                Assert.True(threw);
            }
        }
Пример #22
0
 public void AbortAsyncTasks()
 {
     _asyncTasksQueue.Complete();
 }
        public async Task DequeueAfterCompleteWithData()
        {
            var queue = new AsyncQueue<int>();
            queue.Enqueue(42);
            queue.Complete();
            await queue.WhenCompletedTask.ConfigureAwait(false);
            Assert.Equal(42, await queue.DequeueAsync().ConfigureAwait(false));

            var threw = false;
            try
            {
                await queue.DequeueAsync().ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                threw = true;
            }
            Assert.True(threw);
        }
        public async Task TaskCompletesAsyncWithComplete()
        {
            var queue = new AsyncQueue<int>();

            var tcs = new TaskCompletionSource<bool>();
            var task = queue.DequeueAsync().ContinueWith(
                t =>
                {
                    tcs.Task.Wait();
                    return 0;
                },
                default(CancellationToken),
                TaskContinuationOptions.ExecuteSynchronously,
                TaskScheduler.Default);

            queue.Complete();
            Assert.False(queue.WhenCompletedTask.IsCompleted);
            tcs.SetResult(true);
            await queue.WhenCompletedTask.ConfigureAwait(false);

            // The AsyncQueue<T>.Task property won't complete until all of the 
            // existing DequeueAsync values have also completed.
            Assert.True(task.IsCompleted);
        }
        public async Task TryDequeueAfterComplete()
        {
            var queue = new AsyncQueue<int>();
            queue.Enqueue(13);
            queue.Complete();
            await queue.WhenCompletedTask.ConfigureAwait(false);

            int value;
            Assert.True(queue.TryDequeue(out value));
            Assert.Equal(13, value);
        }
 public void EnqueueAfterComplete()
 {
     var queue = new AsyncQueue<int>();
     queue.Complete();
     Assert.Throws(typeof(InvalidOperationException), () => queue.Enqueue(42));
 }