Пример #1
0
        private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel)
        {
            var inputBuffer = await input.ReadAsync();

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && input.Completion.IsCompleted)
                    {
                        return;
                    }

                    var buffer = channel.Alloc();

                    buffer.Append(ref inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    inputBuffer.Consumed();
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                inputBuffer = await awaiter;
            }
        }
Пример #2
0
        public async Task Range_AllDataReadable_Success(int mode)
        {
            const int Start = 42, Count = 99;

            IReadableChannel <int> c = Channel.CreateFromEnumerable <int>(Enumerable.Range(Start, Count));

            Assert.False(c.Completion.IsCompleted);

            int result;

            for (int i = Start; i < Start + Count; i++)
            {
                switch (mode)
                {
                case 0:     // TryRead
                    Assert.True(c.TryRead(out result));
                    Assert.Equal(i, result);
                    break;

                case 1:     // WaitToReadAsync then TryRead
                    Assert.True(await c.WaitToReadAsync());
                    Assert.True(c.TryRead(out result));
                    Assert.Equal(i, result);
                    break;

                case 2:     // ReadAsync
                    Assert.Equal(i, await c.ReadAsync());
                    break;

                case 3:     // WaitToReadAsync then ReadAsync
                    Assert.True(await c.WaitToReadAsync());
                    Assert.Equal(i, await c.ReadAsync());
                    break;

                case 4:     // Multiple WaitToReadAsync then ReadAsync
                    Assert.True(await c.WaitToReadAsync());
                    Assert.True(await c.WaitToReadAsync());
                    Assert.True(await c.WaitToReadAsync());
                    Assert.True(await c.WaitToReadAsync());
                    Assert.Equal(i, await c.ReadAsync());
                    break;
                }
            }

            Assert.False(await c.WaitToReadAsync());
            Assert.False(await c.WaitToReadAsync());

            Assert.False(c.TryRead(out result));
            Assert.False(c.TryRead(out result));

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());

            await c.Completion;
        }
Пример #3
0
        public async Task SuccessTask_BeforeReadAsync_Success()
        {
            IReadableChannel <int> c = Channel.CreateFromTask(Task.FromResult(42));

            AssertSynchronousTrue(c.WaitToReadAsync());

            Task <int> read = c.ReadAsync().AsTask();

            Assert.Equal(TaskStatus.RanToCompletion, read.Status);
            Assert.Equal(42, read.Result);

            AssertSynchronousFalse(c.WaitToReadAsync());

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());
        }
Пример #4
0
        public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
Пример #5
0
        private async void Consume(IReadableChannel channel)
        {
            while (true)
            {
                var result = await channel.ReadAsync();

                var buffer = result.Buffer;

                try
                {
                    if (buffer.IsEmpty && result.IsCompleted)
                    {
                        break;
                    }

                    await WriteAsync(buffer);
                }
                finally
                {
                    channel.Advance(buffer.End);
                }
            }

            channel.Complete();
        }
Пример #6
0
        private static async Task <int> ReadAsyncAwaited(this IReadableChannel input, Span <byte> destination)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                var sliced = inputBuffer.Slice(0, destination.Length);
                sliced.CopyTo(destination);
                int actual = sliced.Length;
                input.Advance(sliced.End);

                if (actual != 0)
                {
                    return(actual);
                }
                else if (fin)
                {
                    return(0);
                }
            }
        }
Пример #7
0
        public static async Task CopyToAsync(this IReadableChannel input, IWritableChannel output)
        {
            while (true)
            {
                var inputBuffer = await input.ReadAsync();

                var fin = input.Completion.IsCompleted;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(ref inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    inputBuffer.Consumed();
                }
            }
        }
Пример #8
0
        public static async Task CopyToAsync(this IReadableChannel input, Stream stream, int bufferSize, CancellationToken cancellationToken)
        {
            // TODO: Use bufferSize argument
            while (!cancellationToken.IsCancellationRequested)
            {
                var inputBuffer = await input.ReadAsync();

                try
                {
                    if (inputBuffer.IsEmpty && input.Reading.IsCompleted)
                    {
                        return;
                    }

                    foreach (var memory in inputBuffer)
                    {
                        ArraySegment <byte> buffer;

                        if (!memory.TryGetArray(out buffer))
                        {
                            // Fall back to copies if this was native memory and we were unable to get
                            //  something we could write
                            buffer = new ArraySegment <byte>(memory.Span.CreateArray());
                        }

                        await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count);
                    }
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
Пример #9
0
        public static ValueTask <int> ReadAsync(this IReadableChannel input, Span <byte> destination)
        {
            while (true)
            {
                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    break;
                }

                var fin = input.Completion.IsCompleted;

                var inputBuffer = awaiter.GetResult();
                var sliced      = inputBuffer.Slice(0, destination.Length);
                sliced.CopyTo(destination);
                int actual = sliced.Length;
                inputBuffer.Consumed(sliced.End);

                if (actual != 0)
                {
                    return(new ValueTask <int>(actual));
                }
                else if (fin)
                {
                    return(new ValueTask <int>(0));
                }
            }

            return(new ValueTask <int>(input.ReadAsyncAwaited(destination)));
        }
Пример #10
0
        private static async Task Pipes_ReadWriteValues <T>(bool firstWaitToRead, int numItems, Func <int, T> getValue)
        {
            using (AnonymousPipeServerStream serverPipe = new AnonymousPipeServerStream(PipeDirection.Out))
                using (AnonymousPipeClientStream clientPipe = new AnonymousPipeClientStream(PipeDirection.In, serverPipe.ClientSafePipeHandle))
                {
                    IWritableChannel <T> writer = Channel.WriteToStream <T>(serverPipe);
                    IReadableChannel <T> reader = Channel.ReadFromStream <T>(clientPipe);

                    for (int i = 0; i < numItems; i++)
                    {
                        T itemToWrite = getValue(i);

                        Task <T> readItem = firstWaitToRead ?
                                            reader.WaitToReadAsync().ContinueWith(_ => reader.ReadAsync().AsTask()).Unwrap() :
                                            reader.ReadAsync().AsTask();
                        Task writeItem = writer.WriteAsync(itemToWrite);
                        await Task.WhenAll(readItem, writeItem);

                        Assert.Equal(itemToWrite, readItem.Result);
                    }

                    writer.Complete();
                    Assert.False(await reader.WaitToReadAsync());
                    await reader.Completion;
                }
        }
Пример #11
0
        public static async Task CopyToAsync(this IReadableChannel input, Stream stream)
        {
            while (true)
            {
                var inputBuffer = await input.ReadAsync();

                var fin = input.Completion.IsCompleted;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    foreach (var span in inputBuffer)
                    {
                        await stream.WriteAsync(span.Array, span.Offset, span.Length);
                    }
                }
                finally
                {
                    inputBuffer.Consumed();
                }
            }
        }
Пример #12
0
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            int remaining = ContentLength;

            while (remaining > 0)
            {
                var inputBuffer = await _output.ReadAsync();

                var fin = _output.Completion.IsCompleted;

                var consumed = inputBuffer.Start;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var data = inputBuffer.Slice(0, remaining);

                    foreach (var span in data)
                    {
                        await stream.WriteAsync(span.Array, span.Offset, span.Length);
                    }

                    consumed   = data.End;
                    remaining -= data.Length;
                }
                finally
                {
                    inputBuffer.Consumed(consumed);
                }
            }
        }
Пример #13
0
        public void ReadFromStream_Precancellation()
        {
            IReadableChannel <int> r = Channel.ReadFromStream <int>(new MemoryStream());
            var cts = new CancellationTokenSource();

            cts.Cancel();
            AssertSynchronouslyCanceled(r.WaitToReadAsync(cts.Token), cts.Token);
            AssertSynchronouslyCanceled(r.ReadAsync(cts.Token).AsTask(), cts.Token);
        }
Пример #14
0
        /// <summary>Gets an awaiter that enables directly awaiting a channel to read data from it.</summary>
        /// <typeparam name="T">Specifies the type of data in the channel.</typeparam>
        /// <param name="channel">The channel to await and from which to read.</param>
        /// <returns>An awaiter for reading data from the channel.</returns>
        /// <remarks>
        /// Getting the awaiter will initiate a read operation on the channel.
        /// </remarks>
        public static ValueTask <T> .ValueTaskAwaiter GetAwaiter <T>(this IReadableChannel <T> channel)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }

            return(new ValueTask <T> .ValueTaskAwaiter(channel.ReadAsync(), continueOnCapturedContext : true));
        }
Пример #15
0
        public async Task SuccessTask_AfterReadAsync_Success()
        {
            var tcs = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);
            IReadableChannel <int> c = Channel.CreateFromTask(tcs.Task);

            int result;

            Assert.False(c.TryRead(out result));

            Task <int> read = c.ReadAsync().AsTask();

            Assert.False(read.IsCompleted);

            tcs.SetResult(42);
            Assert.Equal(42, await read);

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());
        }
Пример #16
0
        /// <summary>Gets an awaiter that enables directly awaiting a channel to read data from it.</summary>
        /// <typeparam name="T">Specifies the type of data in the channel.</typeparam>
        /// <param name="channel">The channel to await and from which to read.</param>
        /// <returns>An awaiter for reading data from the channel.</returns>
        /// <remarks>
        /// Getting the awaiter will initiate a read operation on the channel.
        /// </remarks>
        public static ValueTaskAwaiter <T> GetAwaiter <T>(this IReadableChannel <T> channel)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }

            return(channel.ReadAsync().GetAwaiter());
        }
Пример #17
0
        public void Precancellation_Reading_ReturnsCanceledImmediately()
        {
            IReadableChannel <int> c = Channel.CreateFromEnumerable(Enumerable.Empty <int>());
            var cts = new CancellationTokenSource();

            cts.Cancel();

            AssertSynchronouslyCanceled(c.ReadAsync(cts.Token).AsTask(), cts.Token);
            AssertSynchronouslyCanceled(c.WaitToReadAsync(cts.Token), cts.Token);
        }
Пример #18
0
        public void Precancellation()
        {
            IReadableChannel <int> c = Channel.CreateFromTask(Task.FromResult(42));

            var cts = new CancellationTokenSource();

            cts.Cancel();

            AssertSynchronouslyCanceled(c.WaitToReadAsync(cts.Token), cts.Token);
            AssertSynchronouslyCanceled(c.ReadAsync(cts.Token).AsTask(), cts.Token);
        }
Пример #19
0
        public async Task FaultedTask_AfterReadAsync()
        {
            var        tcs = new TaskCompletionSource <int>();
            Task <int> t   = tcs.Task;

            IReadableChannel <int> c    = Channel.CreateFromTask(t);
            Task <int>             read = c.ReadAsync().AsTask();

            tcs.SetException(new FormatException());
            Assert.Equal(t.Exception.InnerException, await Assert.ThrowsAsync <FormatException>(() => c.Completion));
            Assert.Equal(t.Exception.InnerException, await Assert.ThrowsAsync <FormatException>(() => read));
        }
        private static async Task CopyCompletedAsync(IReadableChannel input, IWritableChannel channel)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = channel.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
Пример #21
0
        public async Task CanceledTask_AfterReadAsync()
        {
            var        tcs = new TaskCompletionSource <int>();
            Task <int> t   = tcs.Task;

            IReadableChannel <int> c    = Channel.CreateFromTask(t);
            Task <int>             read = c.ReadAsync().AsTask();

            tcs.SetCanceled();
            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.Completion);

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => read);
        }
Пример #22
0
        private static async Task <ChannelReadResult> ReadAtLeastSlowAsync(ReadableChannelAwaitable awaitable, IReadableChannel input, int minimumRequiredBytes, CancellationToken cancellationToken)
        {
            var result = await awaitable;

            while (!result.IsCompleted && result.Buffer.Length < minimumRequiredBytes)
            {
                cancellationToken.ThrowIfCancellationRequested();
                input.Advance(
                    consumed: result.Buffer.Start,
                    examined: result.Buffer.End);
                result = await input.ReadAsync(/* cancelToken */);
            }
            return(result);
        }
Пример #23
0
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            int remaining = ContentLength;

            while (remaining > 0)
            {
                var result = await _output.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                var consumed = inputBuffer.Start;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var data = inputBuffer.Slice(0, remaining);

                    foreach (var memory in data)
                    {
                        ArraySegment <byte> buffer;

                        unsafe
                        {
                            if (!memory.TryGetArray(out buffer))
                            {
                                // Fall back to copies if this was native memory and we were unable to get
                                //  something we could write
                                buffer = new ArraySegment <byte>(memory.Span.ToArray());
                            }
                        }

                        await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count);
                    }

                    consumed   = data.End;
                    remaining -= data.Length;
                }
                finally
                {
                    _output.Advance(consumed);
                }
            }
        }
Пример #24
0
        public async Task CanceledTask_BeforeCreation()
        {
            Task <int> t = Task.FromCanceled <int>(new CancellationToken(true));

            IReadableChannel <int> c = Channel.CreateFromTask(t);

            Assert.Equal(TaskStatus.Canceled, c.Completion.Status);

            AssertSynchronousFalse(c.WaitToReadAsync());
            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());

            int result;

            Assert.False(c.TryRead(out result));
            Assert.Equal(0, result);
        }
Пример #25
0
        public async Task FaultedTask_BeforeCreation()
        {
            Task <int> t = Task.FromException <int>(new FormatException());

            IReadableChannel <int> c = Channel.CreateFromTask(t);

            Assert.Equal(TaskStatus.Faulted, c.Completion.Status);
            Assert.Same(t.Exception.InnerException, c.Completion.Exception.InnerException);

            AssertSynchronousFalse(c.WaitToReadAsync());
            await Assert.ThrowsAsync <FormatException>(() => c.ReadAsync().AsTask());

            int result;

            Assert.False(c.TryRead(out result));
            Assert.Equal(0, result);
        }
        public static async Task <ReadableBuffer> ReadToEndAsync(this IReadableChannel input)
        {
            while (true)
            {
                // Wait for more data
                var result = await input.ReadAsync();

                if (result.IsCompleted)
                {
                    // Read all the data, return it
                    return(result.Buffer);
                }

                // Don't advance the buffer so remains in buffer
                input.Advance(result.Buffer.Start, result.Buffer.End);
            }
        }
Пример #27
0
        private static async Task ReadItems(IReadableChannel <int> readEnd)
        {
            while (!readEnd.Completion.IsCompleted)
            {
                try
                {
                    var item = await readEnd.ReadAsync();

                    Console.WriteLine($"Received: {item}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Receiver Threw: {ex}");
                    return;
                }
            }
            Console.WriteLine("Channel completed");
        }
Пример #28
0
        public async Task FaultedTask_AfterCreation()
        {
            var        tcs = new TaskCompletionSource <int>();
            Task <int> t   = tcs.Task;

            IReadableChannel <int> c = Channel.CreateFromTask(t);

            tcs.SetException(new FormatException());

            Assert.Equal(t.Exception.InnerException, await Assert.ThrowsAsync <FormatException>(() => c.Completion));

            AssertSynchronousFalse(c.WaitToReadAsync());
            await Assert.ThrowsAsync <FormatException>(() => c.ReadAsync().AsTask());

            int result;

            Assert.False(c.TryRead(out result));
            Assert.Equal(0, result);
        }
Пример #29
0
        public async Task CanceledTask_AfterCreation()
        {
            var        tcs = new TaskCompletionSource <int>();
            Task <int> t   = tcs.Task;

            IReadableChannel <int> c = Channel.CreateFromTask(t);

            tcs.SetCanceled();

            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.Completion);

            AssertSynchronousFalse(c.WaitToReadAsync());
            await Assert.ThrowsAnyAsync <InvalidOperationException>(() => c.ReadAsync().AsTask());

            int result;

            Assert.False(c.TryRead(out result));
            Assert.Equal(0, result);
        }
Пример #30
0
        private async Task HandleReceivedAsync(IPooledBuffer item)
        {
            ITransportHeader header;

            using (item)
            {
                header = _deserializer.Deserialize(item);
            }
            try
            {
                var payload            = Maybe <IPooledBuffer> .Nothing;
                var expectedBodyLength = GetBodyLengthHandler.Instance.Handle(header);
                if (expectedBodyLength.HasValue)
                {
                    var body = await _connection.ReadAsync().ConfigureAwait(false);

                    if (body.Count != expectedBodyLength.Value)
                    {
                        body.Dispose();
                        throw new InvalidOperationException(
                                  $"Received body length {body.Count} does not equal to the specified in header: {header}");
                    }
                    payload = new Maybe <IPooledBuffer>(body);
                }
                try
                {
                    var transportMessage = new TransportMessage(header, payload);
                    _log.Debug("Message received: {0}", transportMessage);
                    await _buffer.Out.WriteAsync(transportMessage).ConfigureAwait(false);
                }
                catch
                {
                    payload.GetValueOrDefault()?.Dispose();
                    throw;
                }
            }
            catch
            {
                header.Dispose();
                throw;
            }
        }