Beispiel #1
0
        public async Task CollectionShouldBlockOnMaxBuffer()
        {
            var collection = new AsyncCollection <int>();
            var task       = Task.Factory.StartNew(() => collection.AddRange(Enumerable.Range(0, 10)));
            await TaskTest.WaitFor(() => collection.Count >= 9);

            Assert.That(collection.Count, Is.EqualTo(9), "Buffer should block at 9 items.");
            Assert.That(task.IsCompleted, Is.False, "Task should be blocking on last item.");
            var item = collection.Pop();
            await TaskTest.WaitFor(() => task.IsCompleted);

            Assert.That(task.IsCompleted, Is.True, "Task should complete after room is made in buffer.");
            Assert.That(collection.Count, Is.EqualTo(9), "There should now be 9 items in the buffer.");
        }
        private async Task ProcessNetworkstreamTasksReadTask(NetworkStream netStream)
        {
            Task lastReadTask = Task.FromResult(true);

            while (_disposeToken.IsCancellationRequested == false && netStream != null)
            {
                await lastReadTask;
                bool  hasAvailableData = await _readTaskQueue.OnHasDataAvailablebool(_disposeToken.Token);

                if (!hasAvailableData)
                {
                    return;
                }
                var read = _readTaskQueue.Pop();
                lastReadTask = ProcessReadTaskAsync(netStream, read);
            }
        }
        private void ProcessNetworkstreamTasks(Stream netStream)
        {
            Task writeTask = Task.FromResult(true);
            Task readTask  = Task.FromResult(true);

            //reading/writing from network steam is not thread safe
            //Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization.
            //As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference
            //between read and write threads and no synchronization is required.
            //https://msdn.microsoft.com/en-us/library/z2xae4f4.aspx
            while (_disposeToken.IsCancellationRequested == false && netStream != null)
            {
                Task sendDataReady = Task.WhenAll(writeTask, _sendTaskQueue.OnHasDataAvailable(_disposeToken.Token));
                Task readDataReady = Task.WhenAll(readTask, _readTaskQueue.OnHasDataAvailable(_disposeToken.Token));

                Task.WaitAny(sendDataReady, readDataReady);

                var exception = new[] { writeTask, readTask }
                .Where(x => x.IsFaulted && x.Exception != null)
                .SelectMany(x => x.Exception.InnerExceptions)
                .FirstOrDefault();

                if (exception != null)
                {
                    throw exception;
                }

                if (sendDataReady.IsCompleted)
                {
                    writeTask = ProcessSentTasksAsync(netStream, _sendTaskQueue.Pop());
                }
                if (readDataReady.IsCompleted)
                {
                    readTask = ProcessReadTaskAsync(netStream, _readTaskQueue.Pop());
                }
            }
        }
 public void CollectionShouldBlockOnMaxBuffer()
 {
     var collection = new AsyncCollection<int>();
     var task = Task.Factory.StartNew(() => collection.AddRange(Enumerable.Range(0, 10)));
     TaskTest.WaitFor(() => collection.Count >= 9);
     Assert.That(collection.Count, Is.EqualTo(9), "Buffer should block at 9 items.");
     Assert.That(task.IsCompleted, Is.False, "Task should be blocking on last item.");
     var item = collection.Pop();
     TaskTest.WaitFor(() => task.IsCompleted);
     Assert.That(task.IsCompleted, Is.True, "Task should complete after room is made in buffer.");
     Assert.That(collection.Count, Is.EqualTo(9), "There should now be 9 items in the buffer.");
 }