From f88ed02735ff49973a1d816b565a0c147da883ca Mon Sep 17 00:00:00 2001 From: nils2525 Date: Tue, 3 Nov 2026 04:38:38 -0800 Subject: [PATCH 1/2] Fixed cancellation source disposal race in CloseAsync (#300) --- .../Default/CryptoExchangeWebSocketClient.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CryptoExchange.Net/Sockets/Default/CryptoExchangeWebSocketClient.cs b/CryptoExchange.Net/Sockets/Default/CryptoExchangeWebSocketClient.cs index ce119f62..a05f960a 100644 --- a/CryptoExchange.Net/Sockets/Default/CryptoExchangeWebSocketClient.cs +++ b/CryptoExchange.Net/Sockets/Default/CryptoExchangeWebSocketClient.cs @@ -446,18 +446,16 @@ namespace CryptoExchange.Net.Sockets.Default if (_closeTask?.IsCompleted == false) { _logger.SocketCloseAsyncWaitingForExistingCloseTask(Id); - await _closeTask.ConfigureAwait(false); - return; } - - if (!IsOpen) + else { - _logger.SocketCloseAsyncSocketNotOpen(Id); - return; - } + if (!IsOpen) + _logger.SocketCloseAsyncSocketNotOpen(Id); + else + _logger.SocketClosing(Id); - _logger.SocketClosing(Id); - _closeTask = CloseInternalAsync(); + _closeTask = CloseInternalAsync(); + } } finally { @@ -465,8 +463,11 @@ namespace CryptoExchange.Net.Sockets.Default } await _closeTask.ConfigureAwait(false); + + // Processing may still be running after the socket closes; finish before the caller disposes it. if(_processTask != null) await _processTask.ConfigureAwait(false); + await (OnClose?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false); _logger.SocketClosed(Id); } From e45fa235e083314cb69f508181a4ea4e60baf815 Mon Sep 17 00:00:00 2001 From: nils2525 Date: Tue, 3 Nov 2026 04:39:50 -0800 Subject: [PATCH 2/2] Fixed socket cleanup after connection failures (#301) --- CryptoExchange.Net/Clients/SocketApiClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CryptoExchange.Net/Clients/SocketApiClient.cs b/CryptoExchange.Net/Clients/SocketApiClient.cs index 493cf010..de972eba 100644 --- a/CryptoExchange.Net/Clients/SocketApiClient.cs +++ b/CryptoExchange.Net/Clients/SocketApiClient.cs @@ -899,6 +899,8 @@ namespace CryptoExchange.Net.Clients return connectResult; } + // Remove the connection and stop any reconnect processing before disposing it. + await socketConnection.CloseAsync().ConfigureAwait(false); socketConnection.Dispose(); return connectResult; }