private async Task <ReceivedMqttPacket> ReceiveAsync(CancellationToken cancellationToken) { var fixedHeader = await MqttPacketReader.ReadFixedHeaderAsync(_channel, _fixedHeaderBuffer, _singleByteBuffer, cancellationToken).ConfigureAwait(false); try { ReadingPacketStarted?.Invoke(this, EventArgs.Empty); if (fixedHeader.RemainingLength == 0) { return(new ReceivedMqttPacket(fixedHeader.Flags, null)); } var body = new byte[fixedHeader.RemainingLength]; var bodyOffset = 0; var chunkSize = Math.Min(ReadBufferSize, fixedHeader.RemainingLength); do { var bytesLeft = body.Length - bodyOffset; if (chunkSize > bytesLeft) { chunkSize = bytesLeft; } #if WINDOWS_UWP var readBytes = await _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false); #else // async/await is not used to avoid the overhead of context switches. We assume that the reamining data // has been sent from the sender directly after the initial bytes. //var readBytes = _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); var readBytes = AsyncContext.Run(async() => await _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false)); #endif cancellationToken.ThrowIfCancellationRequested(); ExceptionHelper.ThrowIfGracefulSocketClose(readBytes); bodyOffset += readBytes; } while (bodyOffset < body.Length); return(new ReceivedMqttPacket(fixedHeader.Flags, new MqttPacketBodyReader(body, 0, body.Length))); } finally { ReadingPacketCompleted?.Invoke(this, EventArgs.Empty); } }
private async Task <MqttReceivedPacket> ReceiveAsync(CancellationToken cancellationToken) { var fixedHeader = await MqttPacketReader.ReadFixedHeaderAsync(_channel, _fixedHeaderBuffer, _singleByteBuffer, cancellationToken).ConfigureAwait(false); try { ReadingPacketStarted?.Invoke(this, EventArgs.Empty); if (fixedHeader.RemainingLength == 0) { return(new MqttReceivedPacket(fixedHeader.Flags, null)); } var body = new byte[fixedHeader.RemainingLength]; var bodyOffset = 0; var chunkSize = Math.Min(ReadBufferSize, fixedHeader.RemainingLength); do { var bytesLeft = body.Length - bodyOffset; if (chunkSize > bytesLeft) { chunkSize = bytesLeft; } //async/await不用于避免上下文切换的开销。我们假设扩孔数据已从发件人直接发送到初始字节之后。 var readBytes = _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); cancellationToken.ThrowIfCancellationRequested(); ExceptionHelper.ThrowIfGracefulSocketClose(readBytes); bodyOffset += readBytes; } while (bodyOffset < body.Length); return(new MqttReceivedPacket(fixedHeader.Flags, new MqttPacketBodyReader(body, 0, body.Length))); } finally { ReadingPacketCompleted?.Invoke(this, EventArgs.Empty); } }