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; } }
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; }
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()); }
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); } } }
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(); }
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); } } }
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(); } } }
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); } } }
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))); }
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; } }
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(); } } }
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); } } }
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); }
/// <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)); }
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()); }
/// <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()); }
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); }
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); }
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; } }
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); }
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); }
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); } } }
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); }
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); } }
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"); }
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); }
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); }
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; } }