diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs index 6134d85656cc2..d21e80ba41fee 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs @@ -135,9 +135,10 @@ public override string? SubProtocol internal Task ConnectAsync(Uri uri, List? requestedSubProtocols, CancellationToken cancellationToken) { + AbortIfCancelationRequested(cancellationToken); + lock (_lockObject) { - cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (FastState != WebSocketState.None) @@ -184,7 +185,6 @@ public override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string? // this validation should be synchronous WebSocketValidate.ValidateCloseStatus(closeStatus, statusDescription); - cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); return CloseAsyncCore(closeStatus, statusDescription, false, cancellationToken); @@ -195,7 +195,6 @@ public override Task CloseAsync(WebSocketCloseStatus closeStatus, string? status // this validation should be synchronous WebSocketValidate.ValidateCloseStatus(closeStatus, statusDescription); - cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); return CloseAsyncCore(closeStatus, statusDescription, true, cancellationToken); @@ -284,6 +283,17 @@ private void ThrowIfDisposed() } // lock } + private void AbortIfCancelationRequested(CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + lock (_lockObject) + { + Abort(); + } // lock + cancellationToken.ThrowIfCancellationRequested(); + } + } private void CreateCore(Uri uri, List? requestedSubProtocols) { @@ -366,7 +376,6 @@ private async Task SendAsyncCore(ArraySegment buffer, WebSocketMessageType { lock (_lockObject) { - cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); previousState = FastState; @@ -374,6 +383,7 @@ private async Task SendAsyncCore(ArraySegment buffer, WebSocketMessageType { throw new InvalidOperationException(SR.net_WebSockets_NotConnected); } + AbortIfCancelationRequested(cancellationToken); if (buffer.Count == 0) { @@ -416,7 +426,6 @@ private async Task ReceiveAsyncCore(ArraySegment b { lock (_lockObject) { - cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); previousState = FastState; @@ -424,6 +433,7 @@ private async Task ReceiveAsyncCore(ArraySegment b { throw new WebSocketException(WebSocketError.InvalidState, SR.Format(SR.net_WebSockets_InvalidState, previousState, "Open, CloseSent")); } + AbortIfCancelationRequested(cancellationToken); Memory bufferMemory = buffer.AsMemory(); pinBuffer = bufferMemory.Pin(); @@ -502,22 +512,22 @@ private async Task CloseAsyncCore(WebSocketCloseStatus closeStatus, string? stat WebSocketState previousState; lock (_lockObject) { - cancellationToken.ThrowIfCancellationRequested(); - previousState = FastState; if (_aborted) { return; } + if (previousState == WebSocketState.None || previousState == WebSocketState.Closed) + { + throw new WebSocketException(WebSocketError.InvalidState, SR.Format(SR.net_WebSockets_InvalidState, previousState, "Connecting, Open, CloseSent, CloseReceived, Aborted")); + } + AbortIfCancelationRequested(cancellationToken); + if (!_closeReceived) { _closeStatus = closeStatus; _closeStatusDescription = statusDescription; } - if (previousState == WebSocketState.None || previousState == WebSocketState.Closed) - { - throw new WebSocketException(WebSocketError.InvalidState, SR.Format(SR.net_WebSockets_InvalidState, previousState, "Connecting, Open, CloseSent, Aborted")); - } _closeSent = true; @@ -544,7 +554,6 @@ private async Task CancellationHelper(Task promise, CancellationToken cancellati { try { - cancellationToken.ThrowIfCancellationRequested(); if (promise.IsCompletedSuccessfully) { disposable?.Dispose(); @@ -556,6 +565,7 @@ private async Task CancellationHelper(Task promise, CancellationToken cancellati await promise.ConfigureAwait(false); return; } + AbortIfCancelationRequested(cancellationToken); using (var receiveRegistration = cancellationToken.Register(static s => {