diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index d7d7a88970375e..4297c50fc0be50 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -245,9 +245,10 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) _requestCompletionState = StreamCompletionState.Failed; Complete(); + + SendReset(); } - SendReset(); if (signalWaiter) { _waitSource.SetResult(true); @@ -275,17 +276,17 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) sendReset = _responseCompletionState == StreamCompletionState.Failed; Complete(); } - } - if (sendReset) - { - SendReset(); - } - else - { - // Send EndStream asynchronously and without cancellation. - // If this fails, it means that the connection is aborting and we will be reset. - _connection.LogExceptions(_connection.SendEndStreamAsync(StreamId)); + if (sendReset) + { + SendReset(); + } + else + { + // Send EndStream asynchronously and without cancellation. + // If this fails, it means that the connection is aborting and we will be reset. + _connection.LogExceptions(_connection.SendEndStreamAsync(StreamId)); + } } } } @@ -325,7 +326,7 @@ public async ValueTask WaitFor100ContinueAsync(CancellationToken cancellat private void SendReset() { - Debug.Assert(!Monitor.IsEntered(SyncObject)); + Debug.Assert(Monitor.IsEntered(SyncObject)); Debug.Assert(_requestCompletionState != StreamCompletionState.InProgress); Debug.Assert(_responseCompletionState != StreamCompletionState.InProgress); Debug.Assert(_requestCompletionState == StreamCompletionState.Failed || _responseCompletionState == StreamCompletionState.Failed, @@ -336,6 +337,8 @@ private void SendReset() // Don't send a RST_STREAM if we've already received one from the server. if (_resetException == null) { + // If execution reached this line, it's guaranteed that + // _requestCompletionState == StreamCompletionState.Failed or _responseCompletionState == StreamCompletionState.Failed _connection.LogExceptions(_connection.SendRstStreamAsync(StreamId, Http2ProtocolErrorCode.Cancel)); } } @@ -384,9 +387,12 @@ private void Cancel() // When cancellation propagates, SendRequestBodyAsync will set _requestCompletionState to Failed requestBodyCancellationSource?.Cancel(); - if (sendReset) + lock (SyncObject) { - SendReset(); + if (sendReset) + { + SendReset(); + } } if (signalWaiter)