c# - 如何确保在 MessageReciever 关闭期间完成 MessageHandler 委托?
问题描述
我有一项服务,它连续使用MessageReceiver
fromMicrosoft.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 调用。
解决方案
正如MessageReceiver.CloseAsync()提到的如下:
关闭客户端。关闭它打开的连接。
根据我的测试,在被调用之后,MessageReceiver.CloseAsync()
后续调用将失败,因为 的实例已被处置。如果您仍想完成队列消息,则需要创建一个新的.CompleteAsync
DeadLetterAsync
IMessageReceiver
MessageReceiver
有什么方法可以通过库本身检查操作仍在运行以延迟任务取消?
AFAIK,SDK 目前不提供上述功能。此外,这里有一个类似的关于正常关闭 Azure 服务总线的消息泵的反馈。
当服务停止时,我想给所有操作在进程被杀死之前完成的机会。
对于您的要求,我假设您需要自己实现它,以确保即使在 MessageReceiver 关闭后也可以成功处理接收到的队列消息。或者您可以将CancellationToken
参数传递到您的HandleMessage
方法中以显式取消而不是完成检索到的消息。
推荐阅读
- angular - 通过 Jenkins 部署 dockerized Angular 应用程序的问题
- c# - 如何将 Autofac 与 Asp.net core 2.2 集成
- c# - Type.InvokeMember 在扩展方法中抛出“COMException:类型不匹配”
- ubuntu - 詹金斯连续显示“詹金斯准备工作时请稍候”,我需要做什么?
- hashicorp-vault - 在 docker 中运行 vault 时无法访问 vault ui:找不到 404 页面
- python - 访问路径包含编码字符(如空格)的文件
- python - 算法计算 2^n 的理论与实际时间复杂度
- c# - 没有构造函数的本地化依赖注入
- reactjs - 如何使用 React 测试库通过包含 html 标签的文本字符串进行查询?
- amazon-web-services - 每当将 0 kb 文件上传到 s3 时,是否可以通过 SNS 或 SQS 发送电子邮件通知?