当我致电QueueClient.Close()
时,它总是会引发异常:
由于实体已关闭,因此无法执行操作 或中止。
即使队列为空,也会引发异常。
虽然我使用OnMessageOptions.ExceptionReceived
处理它,但它让我烦恼。我的代码有问题吗?
如何优雅地停止QueueClient?
[开始,然后停止发送消息]
// 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方法]
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");
});
}
答案 0 :(得分:0)
您可以通过以下方式更新订阅来停止接收所有邮件:
_namespaceManager.UpdateSubscription(new SubscriptionDescription(_strTopic, _strSubscription)
{
Status = EntityStatus.ReceiveDisabled
});
这可能会解决您的问题,即使它并不是您所要求的。 (我也试图找出如何正确关闭()。
您还需要更新状态以便再次开始接收。
答案 1 :(得分:0)
我认为了解IQueueClient接口的工作方式非常重要。收到消息后,您会收到称为CancellationToken的消息。 CancellationToken使您可以配合线程,线程池工作项或Task对象之间的取消。在这种情况下,您需要处理Azure Service Bus连接。这就是我要做的,控制连接是否已关闭,如果是这种情况,我将检查我们收到的消息是否仍然有效。
public async Task<object> ReceiveAsync(Message message, CancellationToken token)
{
//If the connection still open, we do something
if (!token.IsCancellationRequested)
{
...
}
}
答案 2 :(得分:-1)
我在https://msdn.microsoft.com/en-us/library/azure/hh528527.aspx上读到,不应该调用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;