async Task FlushAsync(bool doAsync, CancellationToken cancellationToken) { CheckDisposed(); if (outputIndex == 0) { return; } try { if (doAsync) { await Stream.WriteAsync(output, 0, outputIndex, cancellationToken).ConfigureAwait(false); await Stream.FlushAsync(cancellationToken).ConfigureAwait(false); } else { var network = NetworkStream.Get(Stream); network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(output, 0, outputIndex); Stream.Flush(); } logger.LogClient(output, 0, outputIndex); outputIndex = 0; } catch (Exception ex) { IsConnected = false; if (!(ex is OperationCanceledException)) { cancellationToken.ThrowIfCancellationRequested(); } throw; } }
async Task WriteAsync(byte[] buffer, int offset, int count, bool doAsync, CancellationToken cancellationToken) { CheckDisposed(); ValidateArguments(buffer, offset, count); try { var network = NetworkStream.Get(Stream); int index = offset; int left = count; while (left > 0) { int n = Math.Min(BlockSize - outputIndex, left); if (outputIndex > 0 || n < BlockSize) { // append the data to the output buffer Buffer.BlockCopy(buffer, index, output, outputIndex, n); outputIndex += n; index += n; left -= n; } if (outputIndex == BlockSize) { // flush the output buffer if (doAsync) { await Stream.WriteAsync(output, 0, BlockSize, cancellationToken).ConfigureAwait(false); } else { network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(output, 0, BlockSize); } logger.LogClient(output, 0, BlockSize); outputIndex = 0; } if (outputIndex == 0) { // write blocks of data to the stream without buffering while (left >= BlockSize) { if (doAsync) { await Stream.WriteAsync(buffer, index, BlockSize, cancellationToken).ConfigureAwait(false); } else { network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(buffer, index, BlockSize); } logger.LogClient(buffer, index, BlockSize); index += BlockSize; left -= BlockSize; } } } } catch (Exception ex) { IsConnected = false; if (!(ex is OperationCanceledException)) { cancellationToken.ThrowIfCancellationRequested(); } throw; } }