Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close the Azure ServiceBus QueueClient gracefully?

When I call QueueClient.Close(), it always raises an exception:

The operation cannot be performed because the entity has been closed or aborted.

It raises the exception, even if the queue was empty.

Although I handle it by using OnMessageOptions.ExceptionReceived, but it's annoying me. Is there something wrong with my code?

How to stop the QueueClient gracefully?

[Start, and stop the messaging]

// create a QueueClient with Exception handler.
var queueClient = queueManager.GetStorage<UpdateTriggerQueueClient>();
var options = new OnMessageOptions
{
    AutoComplete = false
};
// When the Close() called, it always handles an exception.
options.ExceptionReceived += (sender, args) => 
    logger.Error("An excepion occurred.", args.Exception);

// prepare a CancellationTokenSource.
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;

// start message pump.
queueClient.OnMessageAsync(async message => 
            await DoWork(message, cancellationToken), options);

// sometime after, stop(cancel) the work.
Task.Delay(5000).Wait();
cancellationTokenSource.Cancel();

// some code to wait every in-progress messages finished.
// ...

// close the client.
queueClient.Close();

[DoWork method]

private async Task DoWork(BrokeredMessage message, CancellationToken cancellationToken)
{
    logger.Trace("begin work");
    // Do something cancellable work.
    await Task.Delay(500, cancellationToken)
        .ContinueWith(async t =>
        {
            // complete the message when the task completed,
            // otherwise, abandon the message.
            if (t.Status == TaskStatus.RanToCompletion)
            {
                await message.CompleteAsync();
            }
            else
            {
                await message.AbandonAsync();
            }
        })
        .ContinueWith(t =>
        {
            // cleanup
            logger.Trace("end work");
        });
}
like image 789
Gongdo Gong Avatar asked Feb 03 '26 20:02

Gongdo Gong


1 Answers

You can stop all messages from being recieved by updating the subscription with:

_namespaceManager.UpdateSubscription(new SubscriptionDescription(_strTopic, _strSubscription) 
  { 
     Status = EntityStatus.ReceiveDisabled
  });

This may solve your problem even though it's not exactly what you're asking. (I'm also trying to find out how to close() properly.

You will also need to update the status to begin receiving again.

like image 199
MHill Avatar answered Feb 06 '26 10:02

MHill



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!