public async Task BufferingDataPastEndOfStreamCanBeReadAgain() { var helloBytes = Encoding.ASCII.GetBytes("Hello World"); var stream = new ThrowAfterZeroByteReadStream(helloBytes); PipeReader reader = PipeReader.Create(stream); ReadResult readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; reader.AdvanceTo(buffer.Start, buffer.End); // Make sure IsCompleted is true readResult = await reader.ReadAsync(); buffer = readResult.Buffer; reader.AdvanceTo(buffer.Start, buffer.End); Assert.True(readResult.IsCompleted); var value = await ReadFromPipeAsString(reader); Assert.Equal("Hello World", value); reader.Complete(); }
public async Task CompleteReaderWithoutAdvanceDoesNotThrow() { PipeReader reader = PipeReader.Create(Stream.Null); await reader.ReadAsync(); reader.Complete(); }
public override void Complete(Exception?exception = null) { _inner.Complete(exception); _currentInnerBuffer = ReadOnlySequence <byte> .Empty; _currentDecodedBuffer = ReadOnlySequence <byte> .Empty; }
private async Task SendLoop() { Exception exception = null; try { while (true) { var result = await reader.ReadAsync().ConfigureAwait(false); if (result.IsCanceled) { break; } var buffer = result.Buffer; await SendAsync(buffer).ConfigureAwait(false); reader.AdvanceTo(buffer.End); if (result.IsCompleted) { break; } } } catch (Exception ex) { exception = ex; } reader.Complete(exception); }
/// <summary> /// Read from pipe asynchronously and write to file asynchronously. /// </summary> /// <returns> /// Asynchronous task. /// </returns> /// <param name="writer">Pipe reader.</param> /// <param name="cancellationToken">Token for cancellation.</param> private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken = default) { using (Stream fileStream = new FileStream(TempFilePath, FileMode.Append, FileAccess.Write)) { fileStream.Seek(fileStream.Length, SeekOrigin.Begin); while (true) { var ReadResult = await reader.ReadAsync(cancellationToken); foreach (var buffer in ReadResult.Buffer) { await fileStream.WriteAsync(buffer, cancellationToken); } reader.AdvanceTo(ReadResult.Buffer.End); if (ReadResult.IsCompleted || ReadResult.IsCanceled) { break; } } } reader.Complete(); }
private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken = default) { while (!cancellationToken.IsCancellationRequested) { var result = await reader.ReadAsync(cancellationToken); var buffer = result.Buffer; SequencePosition?position; do { position = buffer.PositionOf((byte)0); if (position != null) { OnMessageReceived(MessageSerializer.DeserializeMessage(buffer.Slice(0, position.Value))); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } } while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
public async Task DataCanBeReadMultipleTimes() { var helloBytes = Encoding.ASCII.GetBytes("Hello World"); var sequence = new ReadOnlySequence <byte>(helloBytes); PipeReader reader = PipeReader.Create(sequence); ReadResult readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; reader.AdvanceTo(buffer.Start, buffer.End); // Make sure IsCompleted is true readResult = await reader.ReadAsync(); buffer = readResult.Buffer; reader.AdvanceTo(buffer.Start, buffer.End); Assert.True(readResult.IsCompleted); var value = await ReadFromPipeAsString(reader); Assert.Equal("Hello World", value); reader.Complete(); }
public async Task CompletingReturnsUnconsumedMemoryToPool() { using (var pool = new DisposeTrackingBufferPool()) { var options = new StreamPipeReaderOptions(pool: pool, bufferSize: 4096, minimumReadSize: 1024); // 2 full segments var stream = new MemoryStream(new byte[options.BufferSize * 3]); PipeReader reader = PipeReader.Create(stream, options); while (true) { ReadResult readResult = await reader.ReadAsync(); reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); if (readResult.IsCompleted) { break; } } Assert.Equal(4, pool.CurrentlyRentedBlocks); reader.Complete(); Assert.Equal(0, pool.CurrentlyRentedBlocks); Assert.Equal(4, pool.DisposedBlocks); } }
public async Task CompleteReaderWithoutAdvanceDoesNotThrow() { PipeReader reader = PipeReader.Create(ReadOnlySequence <byte> .Empty); await reader.ReadAsync(); reader.Complete(); }
public async Task ThrowsOnReadAfterCompleteReader() { PipeReader reader = PipeReader.Create(ReadOnlySequence <byte> .Empty); reader.Complete(); await Assert.ThrowsAsync <InvalidOperationException>(async() => await reader.ReadAsync()); }
private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var result = await reader.ReadAsync(cancellationToken); ReadOnlySequence <byte> buffer = result.Buffer; bool canParse = false; do { canParse = _parser.CanParse(buffer); if (canParse) { ParseResult messageParsed = await _parser.ParseAsync(buffer); _whenMessageParsed.OnNext(messageParsed.CleanMessage); buffer = buffer.Slice(buffer.GetPosition(1, messageParsed.EndPosition)); } }while (canParse); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
public async Task ReadPipeAsync(PipeReader reader, IParserRequestHandler handler) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition?position = null; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var sequence = buffer.Slice(0, position.Value); Logger.Debug("Parsing request..."); Parser.ParseRequestLine(handler, sequence, out var consumed, out var examined); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
public static async Task Echo(PipeReader input, PipeWriter output, ConnectionContext connection) { try { while (true) { var result = await input.ReadAsync(); var request = result.Buffer; if (request.IsEmpty && result.IsCompleted) { input.AdvanceTo(request.End); break; } foreach (var memory in request) { output.Write(memory.Span); } await output.FlushAsync(); input.AdvanceTo(request.End); } } catch { } finally { input.Complete(); output.Complete(); } }
static async Task ReadFromPipe(PipeReader reader, Action <ReadOnlySequence <byte> > operation) { while (true) { var readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; SequencePosition? position = null; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var line = buffer.Slice(0, position.Value); operation?.Invoke(line); var next = buffer.GetPosition(1, position.Value); //等价于popstion+1因为需要包含'\n'; buffer = buffer.Slice(next); //跳过已经读取的数据; } }while (position != null); //指示PipeReader已经消费了多少数据 reader.AdvanceTo(buffer.Start, buffer.End); if (readResult.IsCompleted) { break; } } reader.Complete(); }
protected async Task ReadPipeAsync(PipeReader reader) { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (result.IsCompleted) { break; } ReaderBuffer(result, out consumed, out examined); } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
public async Task ConsumePartialBufferWorks() { // We're using the pipe here as a way to pump bytes into the reader asynchronously var pipe = new Pipe(); PipeReader reader = PipeReader.Create(pipe.Reader.AsStream()); pipe.Writer.WriteEmpty(10); await pipe.Writer.FlushAsync(); ReadResult readResult = await reader.ReadAsync(); Assert.Equal(10, readResult.Buffer.Length); reader.AdvanceTo(readResult.Buffer.GetPosition(4), readResult.Buffer.End); pipe.Writer.WriteEmpty(2); await pipe.Writer.FlushAsync(); readResult = await reader.ReadAsync(); // 6 bytes left over plus 2 newly written bytes Assert.Equal(8, readResult.Buffer.Length); reader.AdvanceTo(readResult.Buffer.End); reader.Complete(); pipe.Writer.Complete(); pipe.Reader.Complete(); }
private async Task ReadPipeAsync(Socket socket, PipeReader reader) { while (true) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; if (result.IsCanceled) { break; } var completed = result.IsCompleted; var pos = ProcessRead(buffer, out consumed, out examined); if (completed) { break; } reader.AdvanceTo(consumed, examined); } reader.Complete(); }
private async Task ExecuteAsync() { Exception sendError = null; try { // Spawn send and receive logic var receiveTask = DoReceive(); var sendTask = DoSend(); if (await Task.WhenAny(receiveTask, sendTask).ConfigureAwait(false) == sendTask) { // Tell the reader it's being aborted _socket.Dispose(); } // Now wait for both to complete await receiveTask; sendError = await sendTask; // Dispose the socket(should noop if already called) _socket.Dispose(); } catch (Exception ex) { Console.WriteLine($"Unexpected exception in {nameof(SocketConnection)}.{nameof(StartAsync)}: " + ex); } finally { // Complete the output after disposing the socket _reader.Complete(sendError); } }
public void Dispose() { _reader.Complete(); _outStream.Dispose(); _stream.Dispose(); _cancelTokenSource.Dispose(); }
private async Task ReadPipeAsync(WebSocket socket, PipeReader reader, CancellationToken token) { while (true) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; do { var line = buffer.Slice(0, myBufferSize); await ProcessLine(socket, line, token); buffer = buffer.Slice(myBufferSize); }while (buffer.Length >= myBufferSize); //We sliced the buffer until no more data could be processed //Tell the PipeReader how much we consumed and how much we left to process reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
static async Task SendToClientAsync(PipeReader reader, TcpClient client) { Stream tcpStream = client.GetStream(); while (true) { ReadResult readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; if (buffer.IsEmpty && readResult.IsCompleted) { break; } foreach (ReadOnlyMemory <byte> segment in buffer) { await tcpStream.WriteAsync(segment); } reader.AdvanceTo(buffer.End); if (readResult.IsCompleted) { break; } } await tcpStream.FlushAsync(); tcpStream.Dispose(); reader.Complete(); }
private async Task PipeProcessorAsync(PipeReader reader, CancellationToken cancelationToken = default) { while (!cancelationToken.IsCancellationRequested) { var result = await reader.ReadAsync(cancelationToken).ConfigureAwait(false); var buffer = result.Buffer; SequencePosition?position; do { position = buffer.PositionOf((byte)'\n'); if (position != null) { var notif = msgProc.PushMessage(buffer.Slice(0, position.Value).ToArray()); if (notif.HasValue) { dispatcher.Invoke(notif.Value); } // +2 = skipping \n\r buffer = buffer.Slice(buffer.GetPosition(2, position.Value)); } } while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted || result.IsCanceled) { break; } } reader.Complete(); }
private static async Task ReadPipeAsync(Socket socket, PipeReader reader) { ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>(); try { while (true) { ReadResult result = await reader.ReadAsync(); buffer = result.Buffer; while (buffer.Length >= BufferSize) { var line = buffer.Slice(0, BufferSize); ProcessLine(socket, line); buffer = buffer.Slice(BufferSize); } //We sliced the buffer until no more data could be processed //Tell the PipeReader how much we consumed and how much we left to process reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } } catch (Exception exc) { Console.WriteLine("Buffer Length: {0}", buffer.Length); Console.WriteLine(exc); } reader.Complete(); }
protected virtual Task OnCloseAsync(Exception?exception, CancellationToken cancellationToken) { // Tell the PipeReader that there's no more data coming _reader.Complete(_exception); return(Task.CompletedTask); }
public async Task ThrowsOnReadAfterCompleteReader() { PipeReader reader = PipeReader.Create(Stream.Null); reader.Complete(); await Assert.ThrowsAsync <InvalidOperationException>(async() => await reader.ReadAsync()); }
static async Task ReadPipeAsync(IReadOnlyDictionary <ushort, IChannel> handlers, PipeReader reader) { while (true) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; while (buffer.TryReadFrame(out Frame frame)) { //TODO: proper memory management instead of copy var slice = buffer.Slice(Constants.HeaderSize, frame.ContentLength); await handlers[frame.Channel].Handle(frame, ref slice); var nextPart = buffer.GetPosition(frame.TotalLength); buffer = buffer.Slice(nextPart); } ; reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } reader.Complete(); }
public Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken) { _input?.Complete(); _output?.Complete(); return(Task.CompletedTask); }
public async Task Execute(PipeReader reader, PipeWriter writer) { List <MemoryHandle> handles = new List <MemoryHandle>(); while (true) { var result = await reader.ReadAsync(); var inputBuffer = result.Buffer; if (inputBuffer.IsEmpty) { if (result.IsCompleted) { break; } reader.AdvanceTo(inputBuffer.End); continue; } var writerBuffer = writer; var buffer = inputBuffer.First; if (buffer.Length > 0) { unsafe { var handle = buffer.Pin(); handles.Add(handle); _inflater.SetInput((IntPtr)handle.Pointer, buffer.Length); var wbuffer = writerBuffer.GetMemory(); handle = wbuffer.Pin(); handles.Add(handle); int written = _inflater.Inflate((IntPtr)handle.Pointer, wbuffer.Length); writerBuffer.Advance(written); var consumed = buffer.Length - _inflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); } } reader.AdvanceTo(inputBuffer.End); await writerBuffer.FlushAsync(); } reader.Complete(); writer.Complete(); _inflater.Dispose(); foreach (var handle in handles) { handle.Dispose(); } }
public override async Task Stop() { if (!started) { return; } cancellationTokenSource.Cancel(); await readerTask; pipeReader.Complete(); pipeWriter.Complete(); pipe.Reset(); started = false; }
private async Task WriteOutputAsync(LibuvOutputConsumer consumer, PipeReader outputReader, Http1Connection http1Connection) { // This WriteOutputAsync() calling code is equivalent to that in LibuvConnection. try { // Ensure that outputReader.Complete() runs on the LibuvThread. // Without ConfigureAwait(false), xunit will dispatch. await consumer.WriteOutputAsync().ConfigureAwait(false); http1Connection.Abort(error: null); outputReader.Complete(); } catch (UvException ex) { http1Connection.Abort(ex); outputReader.Complete(ex); } }