public async Task ReadMessages(PipeReader reader, PacketSource packetSource, CancellationToken ct = default) { try { while (!ct.IsCancellationRequested) { var msg = await reader.ReadAsync(ct).ConfigureAwait(false); if (msg.IsCompleted || msg.IsCanceled || ct.IsCancellationRequested) { break; } if (!TryReadFromBuffer(msg.Buffer, out PacketHeader header, out int headerBytesRead)) { reader.AdvanceTo(msg.Buffer.Start, msg.Buffer.End); } else { switch (header.PacketId) { case PacketHeader.PacketType.Session: if (HandleMessageAndAdvanceBuffer <PacketSessionData>(out var pSessionData)) { _packetHandler.OnPacketSessionData(ref pSessionData, packetSource); } break; case PacketHeader.PacketType.CarSetups: HandleMessageAndAdvanceBuffer <PacketCarSetupData>(out var pCarSetup); { _packetHandler.OnPacketCarSetupData(ref pCarSetup, packetSource); } break; case PacketHeader.PacketType.CarStatus: HandleMessageAndAdvanceBuffer <PacketCarStatusData>(out var pCarStatus); { _packetHandler.OnPacketCarStatusData(ref pCarStatus, packetSource); } break; case PacketHeader.PacketType.CarTelemetry: HandleMessageAndAdvanceBuffer <PacketCarTelemetryData>(out var pTelemetry); { _packetHandler.OnPacketCarTelemetryData(ref pTelemetry, packetSource); } break; case PacketHeader.PacketType.Event: if (HandleMessageAndAdvanceBuffer <PacketEventData>(out var pEvent)) { _packetHandler.OnPacketEventData(ref pEvent, packetSource); } break; case PacketHeader.PacketType.LapData: HandleMessageAndAdvanceBuffer <PacketLapData>(out var pLap); { _packetHandler.OnPacketLapData(ref pLap, packetSource); } break; case PacketHeader.PacketType.Motion: HandleMessageAndAdvanceBuffer <PacketMotionData>(out var pMotion); { _packetHandler.OnPacketMotionData(ref pMotion, packetSource); } break; case PacketHeader.PacketType.Participants: HandleMessageAndAdvanceBuffer <PacketParticipantsData>(out var pParticipants); { _packetHandler.OnPacketParticipantsData(ref pParticipants, packetSource); } break; default: throw new InvalidOperationException( $"Unsupported packet id {header.PacketId}, message should have been filtered before"); } } bool HandleMessageAndAdvanceBuffer <T>(out T sessionData) where T : struct { if (!TryReadFromBuffer <T>(msg.Buffer, out sessionData, out int bytesRead)) { reader.AdvanceTo(msg.Buffer.Start, msg.Buffer.End); return(false); } if (Logger.IsDebugEnabled) { Logger.DebugFormat("Successfully parsed {0}: {1}", typeof(T).Name, sessionData); } reader.AdvanceTo(msg.Buffer.GetPosition(bytesRead)); return(true); } }