public Task FlushAsync(IHttpOutputProducer outputProducer, CancellationToken cancellationToken) { lock (_writeLock) { if (_completed) { return(Task.CompletedTask); } return(_flusher.FlushAsync(0, outputProducer, cancellationToken)); } }
private async Task TimeFlushAsync(long count, IHttpOutputProducer outputProducer, CancellationToken cancellationToken) { _timeoutControl.StartTimingWrite(count); try { await _lastFlushTask; } catch (OperationCanceledException ex) { outputProducer.Abort(new ConnectionAbortedException(CoreStrings.ConnectionOrStreamAbortedByCancellationToken, ex)); } catch { // A canceled token is the only reason flush should ever throw. } _timeoutControl.StopTimingWrite(); cancellationToken.ThrowIfCancellationRequested(); }
public Task FlushAsync(long count = 0, IHttpOutputProducer outputProducer = null, CancellationToken cancellationToken = default) { var flushValueTask = _writer.FlushAsync(cancellationToken); if (flushValueTask.IsCompletedSuccessfully) { return(Task.CompletedTask); } // https://github.com/dotnet/corefxlab/issues/1334 // Pipelines don't support multiple awaiters on flush. // While it's acceptable to call PipeWriter.FlushAsync again before the last FlushAsync completes, // it is not acceptable to attach a new continuation (via await, AsTask(), etc..). In this case, // we find previous flush Task which still accounts for any newly committed bytes and await that. lock (_flushLock) { if (_lastFlushTask.IsCompleted) { _lastFlushTask = flushValueTask.AsTask(); } return(TimeFlushAsync(count, outputProducer, cancellationToken)); } }