{"record":{"id":"e06b33c6078e7cfc","repo":"microsoft/garnet","slug":"garnetclientsession","errorCode":null,"errorMessage":"GarnetClientSession","messagePattern":"GarnetClientSession","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"libs/client/ClientSession/GarnetClientSession.cs","lineNumber":399,"sourceCode":"                    await socket.ConnectAsync(endpoint, cancellationToken).ConfigureAwait(false);\n                }\n            }\n            catch (Exception ex)\n            {\n                logger?.LogWarning(ex, \"Failed at GarnetClient.TryConnectSocketAsync\");\n                socket.Dispose();\n                return false;\n            }\n\n            return true;\n        }\n\n        /// <summary>\n        /// Reconnect to server\n        /// </summary>\n        public Task ReconnectAsync(int timeoutMs = 0, CancellationToken token = default)\n        {\n            if (Disposed) throw new ObjectDisposedException(\"GarnetClientSession\");\n            try\n            {\n                networkSender?.ReturnResponseObject();\n                socket?.Dispose();\n                networkHandler?.Dispose();\n            }\n            catch { }\n            return ConnectAsync(timeoutMs, token);\n        }\n\n        /// <summary>\n        /// Dispose instance\n        /// </summary>\n        public void Dispose()\n        {\n            if (Interlocked.Increment(ref disposed) > 1) return;\n\n            networkSender?.ReturnResponseObject();","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/client/ClientSession/GarnetClientSession.cs#L381-L417","documentation":"ReconnectAsync in GarnetClientSession guards against reuse of a disposed session by checking the Disposed property and throwing ObjectDisposedException named 'GarnetClientSession'. Before reconnecting it attempts to clean up the prior networkSender/networkHandler/socket (swallowing errors) and then calls ConnectAsync. This guard means: once Disposed is true, the session is permanently dead and cannot be resurrected.","triggerScenarios":"Calling ReconnectAsync on a GarnetClientSession after Dispose() (or DisposeAsync) has already run; a retry/reconnect loop that runs after the owning pool or application has torn the session down.","commonSituations":"A reconnect-on-failure policy that outlives the application shutdown; disposing in a finally block but an outstanding reconnect task still fires; using a session from an AsyncPool that was disposed while a reconnect was queued.","solutions":["Track lifecycle explicitly: never call ReconnectAsync after Dispose; cancel any pending reconnect task before disposing.","Create a fresh GarnetClientSession instead of reconnecting a disposed one — Reconnect is for live sessions, not resurrected ones.","Guard the reconnect call site with a disposed flag or ObjectDisposedException handling."],"exampleFix":"// before\nsession.ReconnectAsync();\n\n// after — create a new session if the old one is disposed\nif (session.Disposed)\n    session = new GarnetClientSession(endpoint, ...);\nawait session.ConnectAsync();","handlingStrategy":"validation","validationCode":"if (session is null) throw new ArgumentNullException(nameof(session));\nif (session.Disposed) throw new ObjectDisposedException(nameof(GarnetClientSession));","typeGuard":"if (session?.Disposed ?? true) { /* create a new session instead */ }","tryCatchPattern":"try { await session.ReconnectAsync(); }\ncatch (ObjectDisposedException) { session = new GarnetClientSession(endpoint, ...); await session.ConnectAsync(); }","preventionTips":["Cancel pending reconnect tasks before disposing a session.","Create a fresh session rather than reconnecting a disposed one.","Track lifecycle explicitly so no caller touches a disposed session."],"tags":["csharp","object-disposed","garnet-client-session","connection","lifecycle"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}