c# - 如何确保MessageHandler委托(delegate)在MessageReciever关闭期间完成?

标签 c# .net azure azureservicebus

我有一项服务,它使用来自 Microsoft.Azure.ServiceBusMessageReceiver 连续监听 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/

相关文章:

c# - OpenXML 中的 CellValues.InlineString 和 CellValues.String 有什么区别?

c# - 为什么添加这一行会弄乱我的 NHibernate 映射?

c# - 如何使用 C# 创建推送通知 (FCM)

c# - Word 模板中动态内容的自定义占位符/标签

c# - 在 ASPxTextboxControl 上触发验证后触发 Javascript 函数

c# - 新版本的 CsvHelper 中的 IWriterConfiguration.ReferenceHeaderPrefix 等效项

c# - "IntConverter"的实例存储在哪里?

azure - 通过 ARM 模板覆盖现有 azure 功能应用程序的 appSettings

带有计时器触发器的Azure函数: UnscheduledInvocationReason

rest - 英特尔伽利略 Azure REST 调用