コード例 #1
0
ファイル: MqttClient.cs プロジェクト: zhouhongjie/MQTTnet
        void Cleanup()
        {
            _backgroundCancellationTokenSource?.Cancel(false);
            _backgroundCancellationTokenSource?.Dispose();
            _backgroundCancellationTokenSource = null;

            _publishPacketReceiverQueue?.Dispose();
            _publishPacketReceiverQueue = null;

            _adapter?.Dispose();
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        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();
        }
コード例 #5
0
 public void Dispose()
 {
     FlushCallQueue(null);
     callQueue.Dispose();
     cancellationTokenSource.Cancel();
     connection?.Dispose();
     connection = null;
 }
コード例 #6
0
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         _messageQueue?.Dispose();
     }
     base.Dispose(disposing);
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
            });
        }
コード例 #9
0
        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());
        }
コード例 #10
0
        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);
        }
コード例 #11
0
ファイル: MqttClient.cs プロジェクト: xzsdj/MQTTnet
        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);
                }
            }
        }
コード例 #12
0
        private void UnregisterSubscriberLink()
        {
            lock (gate)
            {
                if (parent != null)
                {
                    parent.RemoveSubscriberLink(this);
                }
            }

            outbox?.Dispose();
            connection?.Dispose();
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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();
        }
コード例 #15
0
        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();
        }
コード例 #16
0
        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();
        }
コード例 #17
0
        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();
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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();
        }
コード例 #20
0
ファイル: FormServer.cs プロジェクト: zeroyou/HPSocket.Net
        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;
        }
コード例 #21
0
        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();
        }
コード例 #22
0
        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();
        }
コード例 #23
0
 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();
         }
     });
 }
コード例 #24
0
        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);
        }
コード例 #25
0
ファイル: AsyncQueueTests.cs プロジェクト: Omsaaf/dotpulsar
        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();
        }
コード例 #26
0
        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);
        }
コード例 #27
0
        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();
        }
コード例 #28
0
        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);
        }
コード例 #29
0
 public void Dispose()
 {
     _messageQueue?.Dispose();
 }
コード例 #30
0
 public void Dispose()
 {
     _disposeToken.Cancel();
     _sendQueue.Dispose();
 }