void Cleanup() { _backgroundCancellationTokenSource?.Cancel(false); _backgroundCancellationTokenSource?.Dispose(); _backgroundCancellationTokenSource = null; _publishPacketReceiverQueue?.Dispose(); _publishPacketReceiverQueue = null; _adapter?.Dispose(); }
public async Task DequeueAsync_GivenTokenIsCanceled_ShouldCancelTask() { //Arrange CancellationTokenSource source1 = new(), source2 = new(); const int excepted = 1; var queue = new AsyncQueue <int>(); var task1 = queue.Dequeue(source1.Token).AsTask(); var task2 = queue.Dequeue(source2.Token).AsTask(); //Act source1.Cancel(); queue.Enqueue(excepted); var exception = await Record.ExceptionAsync(() => task1).ConfigureAwait(false); await task2.ConfigureAwait(false); //Assert exception.Should().BeOfType <TaskCanceledException>(); task2.Result.Should().Be(excepted); //Annihilate source1.Dispose(); source2.Dispose(); queue.Dispose(); }
public async Task DequeueAsync_GivenTokenIsCanceled_ShouldCancelTask() { //Arrange CancellationTokenSource source1 = new CancellationTokenSource(), source2 = new CancellationTokenSource(); const int excepted = 1; var queue = new AsyncQueue <int>(); var task1 = queue.Dequeue(source1.Token); var task2 = queue.Dequeue(source2.Token); //Act source1.Cancel(); queue.Enqueue(excepted); var exception = await Record.ExceptionAsync(() => task1.AsTask()).ConfigureAwait(false); // xUnit can't record ValueTask yet await task2.ConfigureAwait(false); //Assert Assert.IsType <TaskCanceledException>(exception); Assert.Equal(excepted, task2.Result); //Annihilate source1.Dispose(); source2.Dispose(); queue.Dispose(); }
public void AsyncQueue_EnqueueOrderPreservedInCallbacks() { int itemsToProcess = 30; int itemPrevious = -1; var signal = new ManualResetEventSlim(); var asyncQueue = new AsyncQueue <int>(async(item, cancellation) => { // Wait a bit to make sure other enqueue operations can happen in the meantime. await Task.Delay(this.random.Next(50)); Assert.Equal(itemPrevious + 1, item); itemPrevious = item; if (item + 1 == itemsToProcess) { signal.Set(); } }); // Enqueue items quickly, so that next item is likely to be enqueued before the previous callback finishes. for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); } // Wait for all items to be processed. signal.Wait(); signal.Dispose(); asyncQueue.Dispose(); }
public void Dispose() { FlushCallQueue(null); callQueue.Dispose(); cancellationTokenSource.Cancel(); connection?.Dispose(); connection = null; }
protected override void Dispose(bool disposing) { if (disposing) { _messageQueue?.Dispose(); } base.Dispose(disposing); }
public async Task AsyncQueue_DequeueAndDisposeAsync() { int itemsToProcess = 50; // Create a queue in blocking dequeue mode. var asyncQueue = new AsyncQueue <int>(); // List of items collected by the consumer task. var list = new List <int>(); Task consumer = Task.Run(async() => { while (true) { try { int item = await asyncQueue.DequeueAsync(); await Task.Delay(this.random.Next(10) + 1); list.Add(item); } catch (OperationCanceledException) { break; } } }); // Add half of the items slowly, so that the consumer is able to empty the queue. // Add the rest of the items very quickly, so that the consumer won't be able to process all of them. for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); if (i < itemsToProcess / 2) { await Task.Delay(this.random.Next(10) + 5); } } // Give the consumer little more time to process couple more items. await Task.Delay(20); // Dispose the queue, which should cause the first consumer task to terminate. asyncQueue.Dispose(); await consumer; // Check that the list contains items in correct order. for (int i = 0; i < list.Count - 1; i++) { Assert.Equal(list[i] + 1, list[i + 1]); } // Check that not all items were processed. Assert.True(list.Count < itemsToProcess); }
public void DisposeTest() { "调用 AsyncQueue 销毁方法,有 10 个线程在等待出队,将会释放当前所有在等待出队的任务".Test(async() => { // Arrange var asyncQueue = new AsyncQueue <int>(); const int count = 10; var taskList = new Task[count]; for (int i = 0; i < count; i++) { var task = asyncQueue.DequeueAsync(); taskList[i] = task; } // Action asyncQueue.Dispose(); // 等待一下 DequeueAsync 逻辑的完成 await Task.WhenAny(Task.WhenAll(taskList), Task.Delay(TimeSpan.FromSeconds(1))); // Assert foreach (var task in taskList) { Assert.AreEqual(true, task.IsCompleted); } }); "调用 AsyncQueue 销毁方法,有一个线程在等待出队,将会释放当前在等待出队的任务".Test(async() => { // Arrange var asyncQueue = new AsyncQueue <int>(); var task1 = asyncQueue.DequeueAsync(); // Action asyncQueue.Dispose(); // 等待一下 DequeueAsync 逻辑的完成 await Task.Delay(TimeSpan.FromSeconds(1)); // Assert Assert.AreEqual(true, task1.IsCompleted); }); "在 AsyncQueue 进行销毁之前,存在元素没有出队,调用销毁时可以成功销毁".Test(() => { // Arrange var asyncQueue = new AsyncQueue <int>(); asyncQueue.Enqueue(0); asyncQueue.Enqueue(0); // Action asyncQueue.Dispose(); // Assert Assert.AreEqual(0, asyncQueue.Count); }); }
public async Task AsyncQueue_DequeueThrowsAfterDisposeAsync() { // Create a queue in blocking dequeue mode. var asyncQueue = new AsyncQueue <int>(); asyncQueue.Enqueue(1); asyncQueue.Dispose(); await Assert.ThrowsAsync <OperationCanceledException>(async() => await asyncQueue.DequeueAsync()); }
public async Task AsyncQueue_DequeueParallelAsync() { int itemsToProcess = 50; // Create a queue in blocking dequeue mode. var asyncQueue = new AsyncQueue <int>(); // List of items collected by the consumer tasks. var list1 = new List <int>(); var list2 = new List <int>(); using (var cts = new CancellationTokenSource()) { // We create two consumer tasks that compete for getting items from the queue. Task consumer1 = Task.Run(async() => await this.AsyncQueue_DequeueParallelAsync_WorkerAsync(asyncQueue, list1, itemsToProcess - 1, cts)); Task consumer2 = Task.Run(async() => await this.AsyncQueue_DequeueParallelAsync_WorkerAsync(asyncQueue, list2, itemsToProcess - 1, cts)); // Start adding the items. for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); await Task.Delay(this.random.Next(10)); } // Wait until both consumers are finished. Task.WaitAll(consumer1, consumer2); } asyncQueue.Dispose(); // Check that the lists contain items in correct order. for (int i = 0; i < list1.Count - 1; i++) { Assert.True(list1[i] < list1[i + 1]); } for (int i = 0; i < list2.Count - 1; i++) { Assert.True(list2[i] < list2[i + 1]); } // Check that the lists contain all items when merged. list1.AddRange(list2); list1.Sort(); for (int i = 0; i < list1.Count - 1; i++) { Assert.Equal(list1[i] + 1, list1[i + 1]); } // Check that all items were processed. Assert.Equal(list1.Count, itemsToProcess); }
async Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult) { var clientWasConnected = IsConnected; TryInitiateDisconnect(); IsConnected = false; try { if (_adapter != null) { _logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout); await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false); } _logger.Verbose("Disconnected from adapter."); } catch (Exception adapterException) { _logger.Warning(adapterException, "Error while disconnecting from adapter."); } try { var receiverTask = WaitForTaskAsync(_packetReceiverTask, sender); var publishPacketReceiverTask = WaitForTaskAsync(_publishPacketReceiverTask, sender); var keepAliveTask = WaitForTaskAsync(_keepAlivePacketsSenderTask, sender); await Task.WhenAll(receiverTask, publishPacketReceiverTask, keepAliveTask).ConfigureAwait(false); _publishPacketReceiverQueue.Dispose(); } catch (Exception e) { _logger.Warning(e, "Error while waiting for internal tasks."); } finally { Cleanup(); _cleanDisconnectInitiated = false; _logger.Info("Disconnected."); var disconnectedHandler = DisconnectedHandler; if (disconnectedHandler != null) { // This handler must be executed in a new thread because otherwise a dead lock may happen // when trying to reconnect in that handler etc. Task.Run(() => disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception, authenticateResult))).Forget(_logger); } } }
private void UnregisterSubscriberLink() { lock (gate) { if (parent != null) { parent.RemoveSubscriberLink(this); } } outbox?.Dispose(); connection?.Dispose(); }
private void ClearCalls(Exception e) { // dispose queue to ensure no further inserts can happen callQueue.Dispose(); // cancel all other calls var remainingCalls = callQueue.Flush(); foreach (var call in remainingCalls) { call.Tcs.TrySetException(e); } callQueue = new AsyncQueue <CallInfo>(MAX_CALL_QUEUE_LENGTH, true); }
public async Task DequeueAsync_GivenQueueWasNotEmpty_ShouldCompleteDequeueTask() { //Arrange const int expected = 1; var queue = new AsyncQueue <int>(); queue.Enqueue(expected); //Act var actual = await queue.Dequeue().ConfigureAwait(false); //Assert actual.Should().Be(expected); //Annihilate queue.Dispose(); }
public async Task DequeueAsync_GivenQueueWasNotEmpty_ShouldCompleteDequeueTask() { //Arrange const int value = 1; var queue = new AsyncQueue <int>(); queue.Enqueue(value); //Act var actual = await queue.Dequeue().ConfigureAwait(false); //Assert Assert.Equal(value, actual); //Annihilate queue.Dispose(); }
public async Task Enqueue_GivenDequeueTaskWasWaiting_ShouldCompleteDequeueTask() { //Arrange const int value = 1; var queue = new AsyncQueue <int>(); var dequeueTask = queue.Dequeue(); queue.Enqueue(value); //Act var actual = await dequeueTask.ConfigureAwait(false); //Assert Assert.Equal(value, actual); //Annihilate queue.Dispose(); }
public async Task Enqueue_GivenDequeueTaskWasWaiting_ShouldCompleteDequeueTask() { //Arrange const int expected = 1; var queue = new AsyncQueue <int>(); var dequeueTask = queue.Dequeue(); queue.Enqueue(expected); //Act var actual = await dequeueTask.ConfigureAwait(false); //Assert actual.Should().Be(expected); //Annihilate queue.Dispose(); }
public async Task AsyncQueue_DequeueCancellationAsync() { int itemsToProcess = 50; int itemsProcessed = 0; // Create a queue in blocking dequeue mode. var asyncQueue = new AsyncQueue <int>(); Task consumer = Task.Run(async() => { using (var cts = new CancellationTokenSource(250)) { while (true) { try { int item = await asyncQueue.DequeueAsync(cts.Token); await Task.Delay(this.random.Next(10)); itemsProcessed++; } catch (OperationCanceledException) { break; } } } }); for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); await Task.Delay(this.random.Next(10) + 10); } // Check that the consumer task ended already. Assert.True(consumer.IsCompleted); asyncQueue.Dispose(); // Check that not all items were processed. Assert.True(itemsProcessed < itemsToProcess); }
public async Task AsyncQueue_OnlyOneInstanceOfCallbackExecutesAsync() { bool executingCallback = false; int itemsToProcess = 20; int itemsProcessed = 0; var allItemsProcessed = new ManualResetEventSlim(); var asyncQueue = new AsyncQueue <int>(async(item, cancellation) => { // Mark the callback as executing and wait a bit to make sure other callback operations can happen in the meantime. Assert.False(executingCallback); executingCallback = true; await Task.Delay(this.random.Next(100)); itemsProcessed++; if (itemsProcessed == itemsToProcess) { allItemsProcessed.Set(); } executingCallback = false; }); // Adds items quickly so that next item is likely to be enqueued before the previous callback finishes. // We make small delays between enqueue operations, to make sure not all items are processed in one batch. for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); await Task.Delay(this.random.Next(10)); } // Wait for all items to be processed. allItemsProcessed.Wait(); Assert.Equal(itemsToProcess, itemsProcessed); allItemsProcessed.Dispose(); asyncQueue.Dispose(); }
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (_server.HasStarted) { MessageBox.Show(@"请先停止服务", @"服务正在运行:", MessageBoxButtons.OK, MessageBoxIcon.Warning); e.Cancel = true; return; } // 停止消费并释放资源 _asyncQueue.Dispose(); // 停止并释放定时器 _timer.Stop(); _timer.Close(); // 停止释放服务器 _server.Dispose(); e.Cancel = false; }
public async Task DequeueAsync_GivenSequenceOfInput_ShouldReturnSameSequenceOfOutput() { //Arrange const int expected1 = 1, expected2 = 2; var queue = new AsyncQueue <int>(); queue.Enqueue(expected1); queue.Enqueue(expected2); //Act var actual1 = await queue.Dequeue().ConfigureAwait(false); var actual2 = await queue.Dequeue().ConfigureAwait(false); //Assert actual1.Should().Be(expected1); actual2.Should().Be(expected2); //Annihilate queue.Dispose(); }
public async Task DequeueAsync_GivenSequenceOfInput_ShouldReturnSameSequenceOfOutput() { //Arrange const int value1 = 1, value2 = 2; var queue = new AsyncQueue <int>(); queue.Enqueue(value1); queue.Enqueue(value2); //Act var actual1 = await queue.Dequeue().ConfigureAwait(false); var actual2 = await queue.Dequeue().ConfigureAwait(false); //Assert Assert.Equal(value1, actual1); Assert.Equal(value2, actual2); //Annihilate queue.Dispose(); }
public ShareSource(IIterator <T> sourceIterator, int maxQueueLength) { this.SourceIterator = sourceIterator; this.Queue = new AsyncQueue <T>(maxQueueLength); this.readTask = Read(); readTask.ContinueWith(t => { if (t.IsFaulted) { Queue.OnError(t.Exception); } else if (t.IsCompleted) { Queue.OnCompleted(); } else if (t.IsCanceled) { Queue.Dispose(); } }); }
public async Task AsyncQueue_DisposeCancelsAndWaitsEnqueueAsync() { bool signal = true; var asyncQueue = new AsyncQueue <int>(async(item, cancellation) => { // We only set the signal if the wait is finished. await Task.Delay(250); signal = false; }); // Enqueue an item, which should trigger the callback. asyncQueue.Enqueue(1); // Wait a bit and dispose the queue, which should trigger the cancellation. await Task.Delay(100); asyncQueue.Dispose(); Assert.False(signal); }
public async Task DequeueAsync_GivenMultipleDequeues_ShouldCompleteInOrderedSequence() { //Arrange const int value1 = 1, value2 = 2; var queue = new AsyncQueue <int>(); var dequeue1 = queue.Dequeue(); var dequeue2 = queue.Dequeue(); queue.Enqueue(value1); queue.Enqueue(value2); //Act var actual1 = await dequeue1; var actual2 = await dequeue2; //Assert Assert.Equal(value1, actual1); Assert.Equal(value2, actual2); //Annihilate queue.Dispose(); }
public async Task AsyncQueue_DisposeCancelsEnqueueAsync() { bool signal = false; var asyncQueue = new AsyncQueue <int>(async(item, cancellation) => { // We set the signal and wait and if the wait is finished, we reset the signal, but that should not happen. signal = true; await Task.Delay(500, cancellation); signal = false; }); // Enqueue an item, which should trigger the callback. asyncQueue.Enqueue(1); // Wait a bit and dispose the queue, which should trigger the cancellation. await Task.Delay(100); asyncQueue.Dispose(); Assert.True(signal); }
public async Task DequeueAsync_GivenMultipleDequeues_ShouldCompleteInOrderedSequence() { //Arrange const int expected1 = 1, expected2 = 2; var queue = new AsyncQueue <int>(); var dequeue1 = queue.Dequeue(); var dequeue2 = queue.Dequeue(); queue.Enqueue(expected1); queue.Enqueue(expected2); //Act var actual1 = await dequeue1.ConfigureAwait(false); var actual2 = await dequeue2.ConfigureAwait(false); //Assert actual1.Should().Be(expected1); actual2.Should().Be(expected2); //Annihilate queue.Dispose(); }
public async Task AsyncQueue_DisposeCanDiscardItemsAsync() { int itemsToProcess = 100; int itemsProcessed = 0; var asyncQueue = new AsyncQueue <int>(async(item, cancellation) => { // Wait a bit to make sure other enqueue operations can happen in the meantime. await Task.Delay(this.random.Next(30)); itemsProcessed++; }); // Enqueue items quickly, so that next item is likely to be enqueued before the previous callback finishes. for (int i = 0; i < itemsToProcess; i++) { asyncQueue.Enqueue(i); } // Wait a bit, but not long enough to process all items. await Task.Delay(200); asyncQueue.Dispose(); Assert.True(itemsProcessed < itemsToProcess); }
public void Dispose() { _messageQueue?.Dispose(); }
public void Dispose() { _disposeToken.Cancel(); _sendQueue.Dispose(); }