diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs index 4088dab97871..1bb2f832245a 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs @@ -187,17 +187,24 @@ private async Task ProcessReceives() { // Resolve `input` PipeWriter via the IDuplexPipe interface prior to loop start for performance. var input = Input; + + Memory buffer = default; + if (!_waitForData) + { + // Ensure we have some reasonable amount of buffer space to start. + buffer = input.GetMemory(MinAllocBufferSize); + } + while (true) { if (_waitForData) { // Wait for data before allocating a buffer. await _receiver.WaitForDataAsync(); + // Data ready, allocate some memory to receive it. + buffer = input.GetMemory(MinAllocBufferSize); } - // Ensure we have some reasonable amount of buffer space - var buffer = input.GetMemory(MinAllocBufferSize); - var bytesReceived = await _receiver.ReceiveAsync(buffer); if (bytesReceived == 0) @@ -209,6 +216,13 @@ private async Task ProcessReceives() input.Advance(bytesReceived); + if (!_waitForData) + { + // If not waiting for data allocate another buffer before flushing, + // to reduce reader/writer contention on MemoryPool. + buffer = input.GetMemory(MinAllocBufferSize); + } + var flushTask = input.FlushAsync(); var paused = !flushTask.IsCompleted;