# C# - how to manually implement clean teardown and rebuild of all solace managed objects?

**URL:** <https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817>\
**Category:** Solace Event Broker\
**Created:** [April 21, 2026, 6:18am UTC](https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817 "2026-04-21T06:18:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![allmhhuran](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/allmhhuran/32/2272_2.png) [@allmhhuran](https://community.solace.com/u/allmhhuran)\
**Post date:** [April 21, 2026, 6:18am UTC](https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817/1 "2026-04-21T06:18:32Z")

</div>

I am building a “simple” monitor for our pubsub+ broker.

For this moinitor, in the case of some kind of connectivity issue, I would like to tear down and completely rebuild the solace connection from the SDK object level.

I explicitly do not want to use the built in retry functionality in the SDK, because

1. If there was some kind of object initialization problem, the retry will retry with the same configuration. Since the monitor is explicitly for gathering telemetry and service health, it might want to try multiple configurations.
2. I want to retry with exponential backoff and potentially jitter. I beleive the built-in retry does not have backoff (it might have jitter).

The only SDK object which I want to initialize for the lifetime of the monitor application is the ContextFactory itself - ie one call to`ContextFactory.Instance.Init()`

So, the other objects I need to work with are:  
IContext  
ISession  
IFlow  
IQueue  
ITopic

All of these are `IDisposable`, IFlow has `Stop()`, and ISession has `Disconnect()`.

In the case of this monitor, the `IQueue` I am using is a temporary queue - ie, created via `ISession.CreateTemporaryQueue()`. I do not have a need for guaranteed delivery of messages to a monitor queue even when the monitor is not running so that it can get its messages when it reconnects. Loss of messages when the monitor is not running is fine.

If I wanted to tear down all of this cleanly, what is the correct order to do it in?

I currently have this method, which is the anti-method of another method called `CreateSolaceObjects()`:

```auto
private void DisposeSolaceObjects()
{           
    try { _flow?.Stop(); } catch { }
    try { _flow?.Dispose(); } catch { }
    _flow = null;

    try { _queue?.Dispose(); } catch { }
    _queue = null;

    try { _session?.Disconnect(); } catch { }
    try { _session?.Dispose(); } catch { }
    _session = null;

    try { _topic?.Dispose(); } catch { }
    _topic = null;

    try { _context?.Dispose(); } catch { }
    _context = null;
}

```

In my implementation DownError events are routed through a `System.Threading.Channel` to a signal handler background task, which calls this method/anti-method pair as needed.

But when trying to reconnect after a DownError (and after `DisposeSolaceObjects` has been called) I regularly get this error:

> Operation Error: ReturnCode = SOLCLIENT\_FAIL Error Info: (Subcode=MaxClientsForQueueReached, Error string=Max clients exceeded for queue, Response code= 503

How can I avoid this? I would have thought that if everything has been stopped/disconnected and disposed, then the client connection would be gone _and_ the queue would no longer exist (and in the case of a temporary queue, it would be a new queue anyway), so I don’t understand how the “same” queue is still there, _and_ the broker thinks some other client (session? flow?) is still connected to it.

---

<div class="post-metadata">

**Author:** ![cmorgan](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/cmorgan/32/2302_2.png) [@cmorgan](https://community.solace.com/u/cmorgan)\
**Post date:** [April 21, 2026, 5:11pm UTC](https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817/2 "2026-04-21T17:11:55Z")

</div>

> [@allmhhuran](#):
>
> But when trying to reconnect after a DownError (and after `DisposeSolaceObjects` has been called) I regularly get this error:
> 
> > Operation Error: ReturnCode = SOLCLIENT\_FAIL Error Info: (Subcode=MaxClientsForQueueReached, Error string=Max clients exceeded for queue, Response code= 503
> 
> How can I avoid this? I would have thought that if everything has been stopped/disconnected and disposed, then the client connection would be gone _and_ the queue would no longer exist (and in the case of a temporary queue, it would be a new queue anyway), so I don’t understand how the “same” queue is still there, _and_ the broker thinks some other client (session? flow?) is still connected to it.

Given the DownError and lack of network connectivity the client sdk can not signal cleanup of the remote endpoint on the broker. The broker will start a linger timer to hold the endpoint and any bound flows in an attempt to facilitate client reconnection and resuming a flow after reconnection. Only the client sdk with its session reconnect logic can resume a flow. As a result reconnect logic in your application is establishing a flow which is counted against the endpoint MaxBindCount limit (typically defaults to 1).

Given that message loss is acceptable I recommend creating a new temporary endpoint with the same topic subscription when re-establishing the client connection and flow. The messages from the last received message before the DownError to the successful subscription add to the new temporary endpoint will be lost. And the old endpoint will linger for the duration the broker uses to keeps the endpoint for reconnection but eventually will be cleaned up.

---

<div class="post-metadata">

**Author:** ![allmhhuran](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/allmhhuran/32/2272_2.png) [@allmhhuran](https://community.solace.com/u/allmhhuran)\
**Post date:** [April 21, 2026, 10:30pm UTC](https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817/3 "2026-04-21T22:30:10Z")

</div>

That sounds like a good plan, but my expectation was that my `CreateSolaceObjects()` implementation would indeed create new “everythings”. What is required in order to ensure a new temporary endpoint is created? Do I need to pass my own string parameter (name) to `ISession.CreateTemporaryQueue` and ensure that the name is different each time? For example, I could generate a guid and convert it to a string to ensure that every temporary queue gets its own unique name.

---

<div class="post-metadata">

**Author:** ![cmorgan](https://yyz1.discourse-cdn.com/solace/user_avatar/community.solace.com/cmorgan/32/2302_2.png) [@cmorgan](https://community.solace.com/u/cmorgan)\
**Post date:** [April 22, 2026, 2:03pm UTC](https://community.solace.com/t/c-how-to-manually-implement-clean-teardown-and-rebuild-of-all-solace-managed-objects/4817/4 "2026-04-22T14:03:03Z")

</div>

Each call to ISession.CreateTemporaryQueue() should generate a unique name from the broker on each call.

Though if you want direct control on the naming format ISession.CreateTemporaryQueue(string name) is an option.
