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)
{
...
}
}