public void TryEnqueueAfterComplete() { var queue = new AsyncQueue<int>(); Assert.True(queue.TryEnqueue(42)); queue.Complete(); Assert.False(queue.TryEnqueue(42)); }
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)); }
public void EnqueueAfterComplete() { var queue = new AsyncQueue <int>(); queue.Complete(); Assert.Throws <InvalidOperationException>(() => queue.Enqueue(42)); }
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); } }
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); }
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; }
public void TryEnqueueAfterComplete() { var queue = new AsyncQueue <int>(); Assert.True(queue.TryEnqueue(42)); queue.Complete(); Assert.False(queue.TryEnqueue(42)); }
public async Task WaitingCompletedQueueIsFalse() { var queue = new AsyncQueue <int>(); queue.Complete(); Assert.That(await queue.WaitAsync(), Is.False); }
public void WritingCompletedQueueIsFalse() { var queue = new AsyncQueue <int>(); queue.Complete(); Assert.That(queue.TryWrite(1), Is.False); }
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); }
public void UnusedQueueGCPressure() { this.CheckGCPressure( delegate { var queue = new AsyncQueue <GenericParameterHelper>(); queue.Complete(); Assert.True(queue.IsCompleted); }, maxBytesAllocated: 81); }
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); }
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));
/// <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(); }
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); }
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); }
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 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)); }
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); } }
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)); }