首页 > 解决方案 > 如何在 Azure 服务总线选项的 MessageHandlerOptions 中设置自动完成(使用 Net Core 3.1)

问题描述

我正在使用 .NET Core 3.1 编写网络作业,我的触发器如下所示:

public async Task ProcessQueueMessage([ServiceBusTrigger("%ServiceBusProviderConfig:TopicName%", "%ServiceBusProviderConfig:TopicSubscriptionName%", Connection = "ServiceBusConnectionString")] Message message, MessageReceiver messageReceiver, TraceWriter log, TextWriter textWriter)

我正在按照以下要求处理消息并调用完整/死信:

await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);

但是,这会引发错误: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance.

我知道我需要以某种方式将 MessageHandlerOptions 中的 Autocomplete 设置为 false 以使 webjob 不会自动完成它并从队列中删除。

但我很难设置这个值。我试过:

  1. 在 appsettings.json 文件中进行如下设置:

    “扩展”:{“serviceBus”:{“messageHandlerOptions”:{“maxConcurrentCalls”:16,“自动完成”:假}}}

但是在运行时,它不会从此文件中选择设置。我不知道为什么,我怎样才能从本地配置文件中读取设置?

  1. 我还尝试为 MessageHandlerOptions 创建一个对象,但签名缺少必需的参数,这使得它无法做到这一点。例如:

     var messageHandlerOptions = new MessageHandlerOptions(ExceptionHandler)
     {
         AutoComplete = false,
         MaxAutoRenewDuration = new TimeSpan(0, 5, 0), // 5 minutes
         MaxConcurrentCalls = 1,
     };
    
    messageReceiver.RegisterMessageHandler(MessageProcessor, messageHandlerOptions);
    

    静态异步任务 MessageProcessor(Message message, CancellationToken token) { await messageReceiver.CompleteAsync(message.SystemProperties.LockToken); }

我无法访问messageReceiver内部MessageProcessor,这就是为什么这也是不可能的。

谁能建议我如何在配置文件中设置 ServiceBusOptions 以在运行时读取?

仅供参考,我正在使用以下软件包:

1. Microsoft.Azure.ServiceBus Version="4.1.3"
2. Microsoft.Azure.WebJobs.Extensions Version="3.0.0"
3. Microsoft.Azure.WebJobs.Extensions.ServiceBus Version="3.0.0"
4. Microsoft.Azure.WebJobs.Extensions.Storage Version="4.0.2"
5. Microsoft.Azure.WebJobs.Logging.ApplicationInsights Version="3.0.14"

标签: c#azureazure-functionsazureservicebusazure-webjobs

解决方案


经过大量搜索,终于找到了答案。将其发布给任何寻找相同问题的人:

    services.AddServiceBus(options =>
    {
        options.ConnectionString = "ServiceBusConnectionString";
        options.MessageHandlerOptions.AutoComplete = false;
        options.PrefetchCount = 1;
        options.MessageHandlerOptions.MaxConcurrentCalls = 1;
    });

推荐阅读