抛出TaskCanceledException时,Azure ServiceBus队列不重试消息

时间:2019-04-07 08:41:56

标签: c# azure azureservicebus azure-webjobs azure-servicebus-queues

我有一个Azure WebJob函数,用于侦听Azure ServiceBus队列上的消息。通常,当我在代码中遇到异常时,按照this doc

  

SDK在PeekLock模式下接收到一条消息,如果该函数成功完成,则调用该消息上的Complete,如果该函数失败,则调用Abandon。如果该功能的运行时间超过了PeekLock超时时间,则该锁定将自动更新。

根据Azure WebJobs SDK documentation,这意味着该消息再次变为可用,并将被重试:

  

如果应用程序由于某种原因无法处理消息,则可以对收到的消息调用AbandonAsync方法(而不是CompleteAsync)。此方法使Service Bus可以解锁消息并使其可以由同一使用者或另一个竞争使用者再次接收。其次,有一个与锁相关联的超时,如果应用程序在锁定超时到期之前未能处理消息(例如,如果应用程序崩溃),则服务总线将消息解锁并使其可以再次接收(基本上是)默认情况下执行AbandonAsync操作。

上面描述的行为通常会发生,但是我发现了此规则的例外。如果我的代码专门抛出了TaskCanceledException,则该消息将丢弃,

public void ProcessQueueMessage([ServiceBusTrigger("queue")] BrokeredMessage message, TextWriter log)
{
     throw new TaskCanceledException();
}

通过Web作业运行此功能时,我看到错误消息打印成一天,但该消息被使用而没有重试,也没有进入死信队列。如果我将以上TaskCanceledException替换为InvalidOperationException,则该消息将被绑定并重试(应根据实际的ServiceBus队列进行了验证)。

我无法找到此行为的任何解释。目前,我将TaskCanceledException包装在另一个异常中以解决此问题。

问题

我正在遇到Azure WebJobs SDK中的错误吗? TaskCanceledException在这方面是否特殊,或者其他类型的异常是否具有类似的行为?


我正在使用以下NuGet软件包:

  • Microsoft.Azure.WebJobs 2.3.0
  • Microsoft.Azure.WebJobs.ServiceBus 2.3.0

1 个答案:

答案 0 :(得分:0)

如果执行不成功,功能应该放弃该消息。如果您说该消息即使应有也没有被放弃并重试(假设MaxDeliveryCount设置为大于1且接收模式为PeekLock),则可能是问题所在功能而不是Azure Service Bus。您可以通过运行控制台应用程序并执行相同的操作来进行验证,检查消息在何处完成并从队列中删除或仍在队列中,并可供使用。

此外,您似乎正在使用旧版本的WebJobs(和Azure Service Bus)。执行验证时,您需要使用较旧的Azure Service Bus客户端(WindowsAzure.ServiceBus),而不是新的(Microsoft.Azure.ServiceBus)。