public Task FlushAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled(cancellationToken)); } lock (_dataWriterLock) { if (_completed) { return(Task.CompletedTask); } if (_startedWritingDataFrames) { // If there's already been response data written to the stream, just wait for that. Any header // should be in front of the data frames in the connection pipe. Trailers could change things. return(_flusher.FlushAsync(0, this, cancellationToken)); } else { // Flushing the connection pipe ensures headers already in the pipe are flushed even if no data // frames have been written. return(_frameWriter.FlushAsync(this, cancellationToken)); } } }
public Task FlushAsync(IHttpOutputProducer outputProducer, CancellationToken cancellationToken) { lock (_writeLock) { if (_completed) { return(Task.CompletedTask); } return(_flusher.FlushAsync(0, outputProducer, cancellationToken)); } }
private Task WriteAsync( ReadOnlySpan <byte> buffer, CancellationToken cancellationToken = default) { lock (_contextLock) { if (_completed) { return(Task.CompletedTask); } var writer = new BufferWriter <PipeWriter>(_pipeWriter); if (buffer.Length > 0) { writer.Write(buffer); _unflushedBytes += buffer.Length; _totalBytesCommitted += buffer.Length; } writer.Commit(); var bytesWritten = _unflushedBytes; _unflushedBytes = 0; return(_flusher.FlushAsync(bytesWritten, this, cancellationToken)); } }