/// <summary> /// Forwards all bytes coming from a <see cref="PipeReader"/> to the specified <see cref="PipeWriter"/>. /// </summary> /// <param name="reader">The reader to get bytes from.</param> /// <param name="writer">The writer to copy bytes to.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns> /// A <see cref="Task"/> that completes when the <paramref name="reader"/> has finished producing bytes, or an error occurs. /// This <see cref="Task"/> never faults, since any exceptions are used to complete the <paramref name="writer"/>. /// </returns> /// <remarks> /// If an error occurs during reading or writing, the <paramref name="writer"/> is completed with the exception. /// </remarks> internal static Task LinkToAsync(this PipeReader reader, PipeWriter writer, CancellationToken cancellationToken = default) { Requires.NotNull(reader, nameof(reader)); Requires.NotNull(writer, nameof(writer)); return(Task.Run(async delegate { try { while (true) { cancellationToken.ThrowIfCancellationRequested(); var result = await reader.ReadAsync(cancellationToken).ConfigureAwait(false); writer.Write(result.Buffer); reader.AdvanceTo(result.Buffer.End); result.ScrubAfterAdvanceTo(); await writer.FlushAsync(cancellationToken).ConfigureAwait(false); if (result.IsCompleted) { await writer.CompleteAsync().ConfigureAwait(false); break; } } await reader.CompleteAsync().ConfigureAwait(false); } catch (Exception ex) { await writer.CompleteAsync(ex).ConfigureAwait(false); await reader.CompleteAsync(ex).ConfigureAwait(false); } })); }
private async Task ReceiveDataAsync(PipeReader reader, Memory <byte> destinationMemory, CancellationToken cancellationToken) { var position = 0; while (true) { var result = await reader.ReadAsync(cancellationToken); var buffer = result.Buffer; foreach (var memory in buffer) { memory.CopyTo(destinationMemory.Slice(position, memory.Length)); position += memory.Length; } reader.AdvanceTo(buffer.End, buffer.End); if (result.IsCompleted) { break; } } await reader.CompleteAsync(); }
static async Task ReadPipeAsync(PipeReader reader, CsvWriter csvWriter, Mapper mapper) { while (true) { var result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; while (TryReadCarUpdateDatagram(ref buffer, out var completeDatagram)) { var carData = StructSerializer .Deserialize <CarUpdateDatagram>(completeDatagram.ToArray(), 0); var carModel = mapper.Map <CarStateModel>(carData); csvWriter.NextRecord(); csvWriter.WriteRecord(carModel); } reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } await reader.CompleteAsync(); }
/// <summary> /// Liest die Pipe aus, parsed die Daten und gibt diese weiter an die API. (Wird erst beenden, wenn cancellationToken abgebrochen wird) /// </summary> /// <param name="reader">Der Reader von der Pipe, welche ausgelesen werden soll</param> /// <param name="cancellationToken"></param> /// <returns>Wird erst beenden, wenn cancellationToken abgebrochen wird</returns> private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken) { var keepRunning = true; cancellationToken.Register(() => keepRunning = false); while (keepRunning) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; while (this.TryReadMessage(ref buffer, out ReadOnlySequence <byte> line, "\n")) { // Process the line. //this.ProcessLine(line); } // Tell the PipeReader how much of the buffer has been consumed. reader.AdvanceTo(buffer.Start, buffer.End); // Stop reading if there's no more data coming. if (result.IsCompleted) { break; } } // Mark the PipeReader as complete. await reader.CompleteAsync(); }
private async Task RunProcessAsync(PipeReader reader, CancellationToken cancellationToken = default) { ReadResult readResult = default; FlushResult flushResult = default; try { while (!readResult.IsCompleted && !flushResult.IsCompleted) { cancellationToken.ThrowIfCancellationRequested(); readResult = await reader .ReadAsync(cancellationToken); var buffer = readResult.Buffer; var consumed = buffer.Start; var examined = buffer.End; if (await TryProcessPacketAsync(ref buffer, cancellationToken)) { consumed = buffer.Start; examined = consumed; } reader.AdvanceTo(consumed, examined); } } finally { await reader.CompleteAsync(); } }
private async Task ReadPipeAsync(PipeReader reader) { try { int?length = null; while (true) { // Read data written to the pipe that has been made available. var result = await reader.ReadAsync() .ConfigureAwait(false); var buffer = result.Buffer; while (true) { if (!length.HasValue) { if (buffer.Length < sizeof(int)) { // The length prefix has not been received yet. break; } // Enough data is available to read the length prefix. length = ReadLengthPrefix(buffer); // Slice away the part that contains the length prefix. buffer = buffer.Slice(sizeof(int)); } if (buffer.Length < length.Value) { // The remaining data has not been received yet. break; } // Restart the disconnection timer, because a message has just been received. _disconnectTimer.Change(DisconnectTimeout, Timeout.Infinite); DataReceived?.Invoke(this, buffer.Slice(0, length.Value)); // Slice away the bytes that have been processed. buffer = buffer.Slice(length.Value); length = null; } // Mark the processed data as consumed and indicate that the rest has been examined. reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } } finally { await reader.CompleteAsync() .ConfigureAwait(false); } }
private async ValueTask StartReadPipe(PipeReader pipeReader, CancellationToken cancellationToken) { var processor = new PacketsProcessor(_channelWriter); try { while (true) { cancellationToken.ThrowIfCancellationRequested(); var result = await pipeReader.ReadAsync(cancellationToken); var length = await processor.ProcessBytesAsync(result.Buffer, cancellationToken); pipeReader.AdvanceTo(result.Buffer.GetPosition(length)); if (result.IsCompleted) { break; } } } catch (SocketException e) { await pipeReader.CompleteAsync(e); _channelWriter.Complete(e); } }
/// <summary> /// Deserializes the header part of the fits document /// </summary> /// <param name="dataStream">the stream from which to read the data from (should be at position 0)</param> /// <exception cref="InvalidDataException"></exception> public async Task <Header> DeserializeAsync(PipeReader dataStream) { PreValidateStream(dataStream); var endOfHeaderReached = false; var headerEntries = new List <HeaderEntry>(); while (!endOfHeaderReached) { var result = await dataStream.ReadAsync().ConfigureAwait(false); var headerBlock = result.Buffer; if (result.IsCompleted || result.Buffer.Length < HeaderBlockSize) { await dataStream.CompleteAsync().ConfigureAwait(false); throw new InvalidDataException("No END marker found for the fits header, fits file might be corrupted"); } headerEntries.AddRange(ParseHeaderBlock(headerBlock, out endOfHeaderReached)); dataStream.AdvanceTo(result.Buffer.GetPosition(HeaderBlockSize), result.Buffer.End); } return(new Header(headerEntries)); }
protected virtual async Task Receive(PipeReader reader) { try { while (!cancellationToken.IsCancellationRequested) { ReadResult result = await reader.ReadAsync(cancellationToken); if (result.IsCompleted) { break; } ReadOnlySequence <byte> buffer = result.Buffer; while (TryReadLine(ref buffer, out ReadOnlySequence <byte> line)) { await ProcessLine(Id, line); } reader.AdvanceTo(buffer.Start, buffer.End); } } catch (Exception e) { await LogException(e.Message); } finally { await reader.CompleteAsync(); Stop(); Dispose(); } }
private async Task PipeProcessorAsync(PipeReader reader, CancellationToken cancelationToken = default) { while (!cancelationToken.IsCancellationRequested) { var result = await reader.ReadAsync(cancelationToken); 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; } } await reader.CompleteAsync(); }
private static async Task <List <byte[]> > ListenAsync(PipeReader input) { var messages = new List <byte[]>(); const int messageLength = 3; while (true) { var result = await input.ReadAsync(); var buffer = result.Buffer; while (!buffer.IsEmpty) { var payload = buffer.Slice(0, messageLength); messages.Add(payload.ToArray()); buffer = buffer.Slice(messageLength); } input.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } await input.CompleteAsync(); return(messages); }
private static async IAsyncEnumerable <ReadOnlySequence <byte> > GetReaderResult( PipeReader reader, [EnumeratorCancellation] CancellationToken token = default) { while (true && !token.IsCancellationRequested) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; if (buffer.Length < 4) { yield break; } var position = buffer.GetPosition(sizeof(int)); Console.WriteLine("Reading..."); yield return(buffer.Slice(0, position)); buffer = buffer.Slice(position); reader.AdvanceTo(buffer.Start, position); // Tell the PipeReader how much of the buffer has been consumed. // Stop reading if there's no more data coming. if (result.IsCompleted) { break; } } // Mark the PipeReader as complete. await reader.CompleteAsync(); }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { _logger.LogInformation("Worker started"); _payloadReadyEvent.Wait(cancellationToken); _payloadReadyEvent.Reset(); while (!cancellationToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.UtcNow); if (!File.Exists(Constants.EXPECTED_ZIP_FILE_NAME)) { // The package hasn't arrived yet _logger.LogDebug("Compressed payload not found {filename}", Constants.EXPECTED_ZIP_FILE_NAME); await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); continue; } using ZipArchive zipArchive = ZipFile.OpenRead(Constants.EXPECTED_ZIP_FILE_NAME); ZipArchiveEntry dataEntry = zipArchive.Entries.SingleOrDefault(); Stream zipEntryStream = dataEntry.Open(); StreamPipeReaderOptions streamOptions = new StreamPipeReaderOptions(bufferSize: MINIMUM_BUFFER_SIZE); PipeReader pipeReader = PipeReader.Create(zipEntryStream, streamOptions); while (true) { _logger.LogDebug("Reading stream into pipe buffer"); ReadResult result = await pipeReader.ReadAsync(cancellationToken); ReadOnlySequence <byte> buffer = result.Buffer; // Notify the PipeReader how much buffer was used pipeReader.AdvanceTo(buffer.Start, buffer.End); if (!result.IsCompleted) { continue; } _logger.LogDebug("Payload read"); JsonDocument documentFromBuffer = InspectBuffer(buffer); _ = await _payloadChannel.AddPayloadAsync(documentFromBuffer, cancellationToken); break; } await pipeReader.CompleteAsync(); await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); return; } if (cancellationToken.IsCancellationRequested) { _logger.LogWarning("Operation cancelled"); } }
private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var result = await reader.ReadAsync(cancellationToken); var buffer = new ByteReader(result.Buffer); while (!buffer.IsEnd) { try { if (!await ProcessAsync(buffer)) { break; } } catch (Exception ex) { LogError(ex); break; } } // 告诉PipeReader我们已经处理多少缓冲 reader.AdvanceTo(buffer.Start, buffer.End); // 如果没有更多的数据,停止都去 if (result.IsCompleted) { break; } } // 将PipeReader标记为完成 await reader.CompleteAsync(); }
private static async Task ProcessLinesAsync(Socket socket) { Console.WriteLine($"[{socket.RemoteEndPoint}]: connected"); NetworkStream stream = new NetworkStream(socket); PipeReader reader = PipeReader.Create(stream); while (true) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; while (TryReadLine(ref buffer, out ReadOnlySequence <byte> line)) { ProcessLine(line); } reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } await reader.CompleteAsync(); Console.WriteLine($"[{socket.RemoteEndPoint}]: disconnected"); }
public static async IAsyncEnumerable <ResultRow> Reader(PipeReader reader) { var keys = new FastSerializableKeys <string>(); while (true) { var result = await reader.ReadAsync().ConfigureAwait(false); var buffer = result.Buffer; SequencePosition?position; do { position = buffer.PositionOf((byte)'\n'); if (position == null) { continue; } var row = DeserializeRow(keys, buffer.Slice(0, position.Value)); yield return(row); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } await reader.CompleteAsync().ConfigureAwait(false); }
async Task ReadPipeAsync(PipeReader reader) { while (true) { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; while (TryReadLine(ref buffer, out ReadOnlySequence <byte> line)) { // Process the line. ProcessLine(line); } // Tell the PipeReader how much of the buffer has been consumed. reader.AdvanceTo(buffer.Start, buffer.End); // Stop reading if there's no more data coming. if (result.IsCompleted) { break; } } // Mark the PipeReader as complete. await reader.CompleteAsync(); }
private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken = default) { while (true) { if (cancellationToken.IsCancellationRequested) { reader.CancelPendingRead(); await reader.CompleteAsync(); break; } bool isAny = reader.TryRead(out ReadResult result); if (!isAny) { continue; } ReadOnlySequence <byte> buffer = result.Buffer; // In the event that no message is parsed successfully, mark consumed // as nothing and examined as the entire buffer. SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (parser.TryParse(ref buffer, out Message message, out int bConsumed, GetName())) { // A single message was successfully parsed so mark the start as the // parsed buffer as consumed. TryParseMessage trims the buffer to // point to the data after the message was parsed. consumed = buffer.GetPosition(bConsumed); // Examined is marked the same as consumed here, so the next call // to ReadSingleMessageAsync will process the next message if there's // one. examined = consumed; Console.WriteLine(); if (!(message is null)) { foreach (var observer in observers) { observer.OnNext(message); } } } } catch (Exception e) { Console.WriteLine(e); foreach (var observer in observers) { observer.OnError(e); } } finally { reader.AdvanceTo(consumed, examined); } } }
public async Task RunAsync( CancellationToken cancellationToken = default) { mp3dec_t decoder; unsafe { mp3dec_init(&decoder); } try { FlushResult flushResult = default; ReadResult readResult = default; while (!flushResult.IsCompleted) { readResult = await _input.ReadAsync(); var buffer = readResult.Buffer; if (buffer.IsEmpty && readResult.IsCompleted) { return; } while (TryReadFrame(ref buffer, out var frame)) { var block = _outputPipe.Writer.GetMemory( (MINIMP3_MAX_SAMPLES_PER_FRAME * sizeof(short)) + sizeof(short)); var success = TryProcessFrame(frame, ref decoder, block.Span, out var bytesWritten); _outputPipe.Writer.Advance(bytesWritten); // invalid data was passed, so bail out if (!success) { return; } } flushResult = await _outputPipe.Writer.FlushAsync( cancellationToken); _input.AdvanceTo(buffer.Start, buffer.End); } } finally { _ = await _outputPipe.Writer.FlushAsync(cancellationToken); await _input.CompleteAsync(); await _outputPipe.Writer.CompleteAsync(); }
private async Task ReadAsync() { try { while (!_cancellation.IsCancellationRequested) { var result = await _pipeReader.ReadAsync(_cancellation.Token); var buffer = result.Buffer; var readLength = 0L; try { if (0 < buffer.Length) { readLength = OnRead(ref buffer); } if (result.IsCanceled) { readLength = buffer.Length; break; } if (result.IsCompleted) { readLength = buffer.Length; break; } } catch (Exception ex) { readLength = buffer.Length; OnError(ex); break; } finally { _pipeReader.AdvanceTo(buffer.GetPosition(readLength)); } } } catch (OperationCanceledException) { // cancel~ } catch (Exception ex) { OnError(ex); } finally { await _pipeReader.CompleteAsync(); } }
static async Task ProcessMessagesAsync( PipeReader reader, PipeWriter writer) { try { while (true) { ReadResult readResult = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = readResult.Buffer; try { if (readResult.IsCanceled) { break; } if (TryParseLines(ref buffer, out string message)) { FlushResult flushResult = await WriteMessagesAsync(writer, message); if (flushResult.IsCanceled || flushResult.IsCompleted) { break; } } if (readResult.IsCompleted) { if (!buffer.IsEmpty) { throw new InvalidDataException("Incomplete message."); } break; } } finally { reader.AdvanceTo(buffer.Start, buffer.End); } } } catch (Exception ex) { Console.Error.WriteLine(ex); } finally { await reader.CompleteAsync(); await writer.CompleteAsync(); } }
private async Task ReadPipeAsync(PipeReader reader) { try { while (State == EstablishedConnectionState.Opened) { ReadResult result = await reader.ReadAsync(cts.Token).ConfigureAwait(false); ReadOnlySequence <byte> buffer = result.Buffer; if (buffer.Length == 0) { continue; } SequencePosition consumed; SequencePosition examined; try { (consumed, examined) = ReadFrames(ref buffer); Debug.WriteLine($"ADVANCE_TO consumed: {consumed.GetInteger()}, examined: {examined.GetInteger()}"); } catch (Exception ex) { OnError(ErrorCode.FailedToReadFrames, ex); consumed = buffer.End; examined = buffer.End; } reader.AdvanceTo(consumed, examined); if (result.IsCompleted) { break; } } await reader.CompleteAsync().ConfigureAwait(false); } catch (Exception ex) { OnError(ErrorCode.ReadPipe, ex); await reader.CompleteAsync(ex).ConfigureAwait(false); } }
/// <inheritdoc/> public async Task RunAsync( CancellationToken cancellationToken = default) { bool identified = false; _codec = new TaskCompletionSource <MpegAudioCodec>(); try { FlushResult flushResult = default; ReadResult readResult = default; while (!flushResult.IsCompleted) { readResult = await _input.ReadAsync(cancellationToken); var buffer = readResult.Buffer; if (buffer.IsEmpty && readResult.IsCompleted) { return; } while (TryReadMpegFrame(ref buffer, out var frame, out var version, out var layer, out var bitrate, out var samplingRate, out var channelCount)) { if (!identified) { identified = true; _ = _codec.TrySetResult( new MpegAudioCodec(version, layer, samplingRate, channelCount, bitrate)); } if (!TryWriteFrame(frame, _outputPipe.Writer)) { return; } } flushResult = await _outputPipe.Writer.FlushAsync( cancellationToken); _input.AdvanceTo(buffer.Start, buffer.End); } } finally { _ = await _outputPipe.Writer.FlushAsync(cancellationToken); await _input.CompleteAsync(); await _outputPipe.Writer.CompleteAsync(); }
/// <inheritdoc/> public async Task RunAsync( CancellationToken cancellationToken = default) { try { FlushResult flushResult = default; ReadResult readResult = default; while (!flushResult.IsCompleted) { readResult = await _input.ReadAsync(cancellationToken); var buffer = readResult.Buffer; if (buffer.IsEmpty && readResult.IsCompleted) { return; } while (TryHandleElement(ref buffer, out var status)) { if (status == EbmlHandleStatus.NewBlock && !TryWriteBlock(_bestAudioTrack, _outputPipe.Writer, _state.BlockData)) { return; } if (status == EbmlHandleStatus.UnsupportedFile || status == EbmlHandleStatus.NoMoreData) { return; } if (status == EbmlHandleStatus.MissingData) { break; } } flushResult = await _outputPipe.Writer.FlushAsync( cancellationToken); _input.AdvanceTo(buffer.Start, buffer.End); } } finally { _ = await _outputPipe.Writer.FlushAsync(cancellationToken); await _input.CompleteAsync(); await _outputPipe.Writer.CompleteAsync(); }
/// <summary> /// Receive multiple messages from a pipe /// </summary> public static async IAsyncEnumerable <T> ReceiveAsync <T>(PipeReader source, MessagePipeOptions options = default) { if (source == null) { throw new ArgumentNullException(nameof(source)); } options = options.Normalize(); while (true) { // obtain the next buffer options.OnLog("ReceiveAsync obtaining buffer..."); if (!source.TryRead(out var result)) { result = await source.ReadAsync(options.CancellationToken).ConfigureAwait(false); } if (result.IsCanceled) { ThrowCancelled(); } // consume the buffer var buffer = result.Buffer; options.OnLog($"ReceiveAsync got {buffer.Length} bytes"); int processed = 0; while (options.TryRead <T>(ref buffer, out var item)) { processed++; yield return(item); } if (processed == 0 && result.IsCompleted) // check for termination { // we have everything, and there will never be any more; was it clean? if (!buffer.IsEmpty) { ThrowInputCompletedWithPartialPayload(); } break; } // mark what we consumed (the "ref buffer" means we've sliced it already) source.AdvanceTo(buffer.Start, buffer.End); } if (options.MarkComplete) { await source.CompleteAsync().ConfigureAwait(false); } options.OnLog("ReceiveAsync completed successfully"); }
private async Task ProcessMessagesAsync(CancellationToken cancellationToken) { try { while (true) { SequencePosition?position; ReadResult result = await _reader.ReadAsync(cancellationToken); ReadOnlySequence <byte> buffer = result.Buffer; do { position = buffer.PositionOf(SubscriptionSession.Delimiter); if (position is not null) { await _pipeline.ProcessAsync( _connection, buffer.Slice(0, position.Value), cancellationToken); // Skip the message which was read. buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null); _reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { } catch (WebSocketException) { // we will just stop receiving } finally { // reader should be completed always, so that related pipe writer can // stop write new messages await _reader.CompleteAsync(); } }
public async IAsyncEnumerable <IPacket> ReadPacketAsync(TimeSpan timeout, [EnumeratorCancellation] CancellationToken cancellationToken = default) { while (!cancellationToken.IsCancellationRequested) { ReadResult result = await _pipeReader.ReadAsync(cancellationToken) .AsTask() .WithTimeout(timeout, TimeoutConstants.Message); ReadOnlySequence <byte> buffer = result.Buffer; while (!cancellationToken.IsCancellationRequested) { // We can't calculate packet size without the packet header if (buffer.Length < PacketConstants.HeaderSize) { break; } // Make sure the packet fits in the buffer // See: https://mariadb.com/kb/en/library/0-packet/ var bodySize = GetBodySize(buffer); var packetSize = PacketConstants.HeaderSize + bodySize; if (buffer.Length < packetSize) { break; } // Process packet and repeat in case there are more packets in the buffer var packet = TryReadPacket(buffer.Slice(PacketConstants.HeaderSize, bodySize)); if (packet != null) { yield return(packet); } buffer = buffer.Slice(buffer.GetPosition(packetSize)); } _pipeReader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } await _pipeReader.CompleteAsync(); }
public async IAsyncEnumerable <ReadOnlySequence <byte> > Frames([EnumeratorCancellation] CancellationToken cancellationToken) { ThrowIfDisposed(); _ = FillPipe(cancellationToken); try { while (true) { var result = await _reader.ReadAsync(cancellationToken).ConfigureAwait(false); var buffer = result.Buffer; while (true) { if (buffer.Length < 4) { break; } var frameSize = buffer.ReadUInt32(0, true); var totalSize = frameSize + 4; if (buffer.Length < totalSize) { break; } yield return(buffer.Slice(4, frameSize)); buffer = buffer.Slice(totalSize); } if (result.IsCompleted) { break; } _reader.AdvanceTo(buffer.Start); } } finally { await _reader.CompleteAsync().ConfigureAwait(false); } }
private static async Task ProcessMessagesAsync( PipeReader reader, ProcessAsync processAsync, CancellationToken cancellationToken) { try { while (true) { ReadResult result = await reader .ReadAsync(cancellationToken) .ConfigureAwait(false); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition? position = null; do { position = buffer.PositionOf(Delimiter); if (position != null) { await processAsync( buffer.Slice(0, position.Value), cancellationToken) .ConfigureAwait(false); // Skip the message which was read. buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } } while (position != null); reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } } catch (TaskCanceledException) { } finally { await reader.CompleteAsync().ConfigureAwait(false); } }
private async ValueTask ConsumeAsync(PipeReader reader, CancellationToken cancellationToken) { while (true) { var result = await reader.ReadAsync(cancellationToken); var buffer = result.Buffer; reader.AdvanceTo(buffer.End, buffer.End); if (result.IsCompleted) { break; } } await reader.CompleteAsync(); }