首页 > 解决方案 > 如何确保在 MessageReciever 关闭期间完成 MessageHandler 委托?

问题描述

我有一项服务,它连续使用MessageReceiverfromMicrosoft.Azure.ServiceBus来监听 ServiceBus 中的订阅。当服务停止时,我想给所有操作在进程被杀死之前完成的机会。

这是我根据库提供的示例使用的代码:

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仍在运行,服务也会立即终止。

有什么方法可以通过库本身检查操作仍在运行以延迟任务取消?我可以想到一种方法来自己计数,锁定所有正在运行的任务,但我希望有一种更好的方法可以让我知道正在运行的处理程序的数量。

理想情况下,我想注销 Handler 以便消息泵停止,而接收器本身不会关闭以允许例如 CompleteAsync 调用。

标签: c#.netazureazureservicebus

解决方案


正如MessageReceiver.CloseAsync()提到的如下:

关闭客户端。关闭它打开的连接。

根据我的测试,在被调用之后,MessageReceiver.CloseAsync()后续调用将失败,因为 的实例已被处置。如果您仍想完成队列消息,则需要创建一个新的.CompleteAsyncDeadLetterAsyncIMessageReceiverMessageReceiver

有什么方法可以通过库本身检查操作仍在运行以延迟任务取消?

AFAIK,SDK 目前不提供上述功能。此外,这里有一个类似的关于正常关闭 Azure 服务总线的消息泵的反馈。

当服务停止时,我想给所有操作在进程被杀死之前完成的机会。

对于您的要求,我假设您需要自己实现它,以确保即使在 MessageReceiver 关闭后也可以成功处理接收到的队列消息。或者您可以将CancellationToken参数传递到您的HandleMessage方法中以显式取消而不是完成检索到的消息。


推荐阅读