KubeMQ
Client SDKsC#How-to guidesConnection

Close a KubeMQ C# Client

Properly close a KubeMQ C# client connection to release resources and shut down cleanly.

Overview

Closing a client isn't an afterthought — it tells the broker and your own process that this connection is done, so both sides release what they were holding for it. A KubeMQ client is more than a socket: it's a gRPC channel plus whatever callbacks and in-flight operations it's servicing. Skip the close and those linger — the channel stays open — and in short-lived processes or hosted services you leak connections until the process is killed.

Calling DisposeAsync() (or scoping the client with await using) sends a ChannelDisconnect signal to the broker, drains any in-flight callbacks, and only then releases the underlying gRPC resources. Once it returns, the client is in a terminal disposed state.

Gotchas: the drain window is bounded, not unlimited, so a slow consumer can still lose the tail of a burst if you dispose mid-stream; a disposed client is dead forever — no reconnect on the same instance, construct a new one; and when the client's lifetime is tied to application lifecycle events (e.g. IHostedService.StopAsync) rather than a lexical scope, call DisposeAsync() explicitly instead of relying on await using.

Prerequisites

  • KubeMQ server running on localhost:50000
  • C# SDK installed (dotnet add package KubeMQ.SDK.CSharp)

Code

Program.cs
// KubeMQ .NET SDK — Connection: Explicit Close
//
// This example demonstrates manually disposing a client without 'await using'.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - dotnet run

using KubeMQ.Sdk.Client;

var options = new KubeMQClientOptions
{
    Address = "localhost:50000",
    ClientId = "csharp-connection-close-client",
};

var client = new KubeMQClient(options);
await client.ConnectAsync();
Console.WriteLine("Connected. Press Enter to disconnect...");
Console.ReadLine();
await client.DisposeAsync();
Console.WriteLine("Disconnected.");

How It Works

  • The client is created without await using so that the lifetime can be controlled manually.
  • await client.ConnectAsync() opens the gRPC channel; Console.ReadLine() holds the connection open until the user presses Enter.
  • await client.DisposeAsync() sends a ChannelDisconnect signal to the broker, drains any in-flight callbacks, and releases the underlying gRPC resources.
  • Use this pattern when the client lifetime is tied to application lifecycle events (e.g. IHostedService.StopAsync) rather than a lexical scope.

Was this page helpful?

On this page