# Close a KubeMQ C# Client (/sdks/csharp/how-to/connection/close)



## Overview [#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 [#prerequisites]

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

## Code [#code]

```csharp title="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 [#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.

## Related [#related]

* Getting started
* [C# SDK Reference](/sdks/csharp/reference)
* [Connect](/sdks/csharp/tutorials/connect)
* [Ping](/sdks/csharp/how-to/connection/ping)
