C# 如何优雅地关闭Azure ServiceBus QueueClient?

C# 如何优雅地关闭Azure ServiceBus QueueClient?,c#,azure,azureservicebus,C#,Azure,Azureservicebus,当我调用QueueClient.Close()时,它总是引发异常: 无法执行该操作,因为实体已关闭 或者流产 即使队列为空,它也会引发异常 虽然我通过在MessageOptions.ExceptionReceived上使用来处理它,但这让我很恼火。我的代码有问题吗 如何优雅地停止排队客户端? [启动和停止消息传递] // create a QueueClient with Exception handler. var queueClient = queueManager.GetStorage&l

当我调用
QueueClient.Close()
时,它总是引发异常:

无法执行该操作,因为实体已关闭 或者流产

即使队列为空,它也会引发异常

虽然我通过在MessageOptions.ExceptionReceived上使用
来处理它,但这让我很恼火。我的代码有问题吗

如何优雅地停止排队客户端?

[启动和停止消息传递]

// 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();
我读到close不应该被调用,因为连接是由消息工厂管理的

this.mSubscriptionClient.OnMessage(
             (pMessage) =>
             {
                 try
                 {
                     // Will block the current thread if Stop is called.
                     this.mPauseProcessingEvent.WaitOne();

                     // Execute processing task here
                     pProcessMessageTask(pMessage);
                 }
                 catch(Exception ex)
                 {
                     this.RaiseOnLogMessageEvent(pMessage, ex);
                 }
             },
             options);
然后当你准备停下来的时候

this.mPauseProcessingEvent.Reset();
mSubscriptionClient.Close();
数据类型为

private ManualResetEvent mPauseProcessingEvent;

通过更新订阅,您可以停止接收所有邮件,方法是:

_namespaceManager.UpdateSubscription(new SubscriptionDescription(_strTopic, _strSubscription) 
  { 
     Status = EntityStatus.ReceiveDisabled
  });
这可能会解决你的问题,即使这并不是你想要的。(我还试图找出如何正确关闭()


您还需要更新状态以再次开始接收。

我认为了解iqueeClient接口的工作原理很重要。当您收到消息时,您会收到一个称为CancellationToken的消息。CancellationToken使您能够在线程、线程池工作项或任务对象之间配合取消。在他的案例你需要处理Azure服务总线连接。这是我将要做的,控制连接是否已关闭,如果是这种情况,我将检查我们收到的消息是否仍然有效

public async Task<object> ReceiveAsync(Message message, CancellationToken token)
{
            //If the connection still open, we do something
            if (!token.IsCancellationRequested)
            {
             ...
            }
}
public async Task ReceiveAsync(消息消息、取消令牌)
{
//如果连接仍然打开,我们会做些什么
如果(!token.IsCancellationRequested)
{
...
}
}

我调用了
Close
方法,因为我需要停止在QueueClient上接收消息。您能告诉我如何在不调用
Close
的情况下停止接收消息吗?链接到的页面显示“您不应该在发送消息后关闭消息工厂或队列、主题和订阅客户端,然后在发送下一条消息时重新创建它们。”因此,它指的是每次要处理消息时关闭和重新创建客户端,而不是指何时要关闭客户端,因为您已经做好了准备。
public async Task<object> ReceiveAsync(Message message, CancellationToken token)
{
            //If the connection still open, we do something
            if (!token.IsCancellationRequested)
            {
             ...
            }
}