public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
        {
            CheckNotDisposed();

            ValidateBufferArgs(buffer, offset, length);

            if (!IsOpen)
            {
                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
            }

            // Relative offset from "off" argument
            var writtenCount = 0;

            if (_outputBuffer.Length > 0)
            {
                var capa      = (int)(_outputBuffer.Capacity - _outputBuffer.Length);
                var writeSize = capa <= length ? capa : length;
                await _outputBuffer.WriteAsync(buffer, offset, writeSize, cancellationToken).ConfigureAwait(false);

                writtenCount += writeSize;
                if (writeSize == capa)
                {
                    //ArraySegment<byte> bufSegment;
                    //_outputBuffer.TryGetBuffer(out bufSegment);
                    var data = _outputBuffer.ToArray();
                    //await _transport.WriteAsync(bufSegment.Array, cancellationToken).ConfigureAwait(false);
                    await _transport.WriteAsync(data, cancellationToken).ConfigureAwait(false);

                    _outputBuffer.SetLength(0);
                }
            }

            while (length - writtenCount >= _bufSize)
            {
                await _transport.WriteAsync(buffer, offset + writtenCount, _bufSize, cancellationToken).ConfigureAwait(false);

                writtenCount += _bufSize;
            }

            var remain = length - writtenCount;

            if (remain > 0)
            {
                if (_outputBuffer.Capacity < _bufSize)
                {
                    _outputBuffer.Capacity = _bufSize;
                }
                await _outputBuffer.WriteAsync(buffer, offset + writtenCount, remain, cancellationToken).ConfigureAwait(false);
            }
        }
        public override async Task FlushAsync(CancellationToken cancellationToken)
        {
            CheckNotDisposed();

            if (!IsOpen)
            {
                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
            }

            //ArraySegment<byte> bufSegment;
            //_writeBuffer.TryGetBuffer(out bufSegment);
            //var buf = bufSegment.Array;
            var buf = _writeBuffer.ToArray();

            //var len = (int)_writeBuffer.Length;
            var dataLen = (int)_writeBuffer.Length - HeaderSize;

            if (dataLen < 0)
            {
                throw new InvalidOperationException(); // logic error actually
            }

            // Inject message header into the reserved buffer space
            EncodeFrameSize(dataLen, buf);

            // Send the entire message at once
            await _transport.WriteAsync(buf, cancellationToken).ConfigureAwait(false);

            InitWriteBuffer();

            await _transport.FlushAsync(cancellationToken).ConfigureAwait(false);
        }