我有一项服务,它使用来自 Microsoft.Azure.ServiceBus
的 MessageReceiver
连续监听 ServiceBus 中的订阅。当服务停止时,我想在进程被终止之前给所有操作完成的机会。
这是我根据 example 使用的代码图书馆提供:
private async Task StartReceiveLoop(IMessageReceiver receiver, CancellationToken cancellationToken)
{
var doneReceiving = new TaskCompletionSource<bool>();
cancellationToken.Register(() =>
{
receiver.CloseAsync();
doneReceiving.SetResult(true);
});
receiver.RegisterMessageHandler(
async (message, ct) => await HandleMessage(receiver, message),
new MessageHandlerOptions(HandleException));
await doneReceiving.Task;
}
在服务停止时,即使 HandleMessage
仍在运行,我也会取消任务并立即终止服务。
有什么方法可以通过库本身检查操作是否仍在运行以延迟任务取消?我可以想出一种方法,通过锁定所有正在运行的任务来进行自己的计数,但我希望有更好的方法可以让我知道正在运行的处理程序的数量。
理想情况下,我想取消注册处理程序,以便消息泵停止,而接收器本身不会关闭以允许例如CompleteAsync 调用。
最佳答案
如MessageReceiver.CloseAsync()提及如下:
Closes the Client. Closes the connections opened by it.
根据我的测试,在调用 MessageReceiver.CloseAsync()
后,后续调用 CompleteAsync
,DeadLetterAsync
将失败,因为 实例>IMessageReceiver
已被处置。如果您仍想完成队列消息,则需要创建一个新的 MessageReceiver
。
Is there any way that I can check via the library itself that the operation is still running to delay task cancellation?
据我所知,该SDK目前不提供上述功能。而且,这里有一个类似的feedback关于优雅地关闭 Azure 服务总线的消息泵。
When the service is stopped I would like to give a chance for all operations to complete before the process is killed.
对于您的需求,我假设您需要自己实现它,以确保即使在 MessageReceiver 关闭后也能成功处理接收到的队列消息。或者,您可以将 CancellationToken
参数传递到 HandleMessage
方法中以显式取消,而不是完成检索到的消息。
关于c# - 如何确保MessageHandler委托(delegate)在MessageReciever关闭期间完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50943534/