C# - Azure Service Bus - 在给定时间后取消消息处理

时间:2018-04-04 08:39:24

标签: c# azure azureservicebus cancellation-token

我正在构建一个基于服务总线的应用程序。当我的接收器从服务总线获取消息时,可能需要花费大量时间来处理它,所以我想等待处理,但是如果花费太多时间,则应该取消处理并且消息应该是完成。

这是接收者的代码:

client.OnMessageAsync(async message =>
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("message from api");
                    try
                    {
                        CancellationTokenSource source = new CancellationTokenSource();
                        source.CancelAfter(TimeSpan.FromSeconds(30));
                        var task = new Task(() => ProcessServiceBusMessage(message).Wait(), source.Token);

                        await message.CompleteAsync();
                    }
                    catch (Exception ex)
                    {
                        errLog.Error(ex.Message + ex.StackTrace);
                        await message.DeadLetterAsync();
                    }
                }, new OnMessageOptions() { AutoComplete = false, MaxConcurrentCalls = 20, AutoRenewTimeout = new TimeSpan(0, 5, 0) });

正如您所看到的,我在一个任务中启动ProcessServiceBusMessage函数,我等待它并在30秒后使用CancellationToken取消任务(如果消息需要超过30秒到完整处理),但它不起作用。

我该如何解决?

编辑:具体来说,任务在30秒后没有被取消,并且立即执行message.CompleteAsync(),而不等待任务

谢谢。

2 个答案:

答案 0 :(得分:2)

问题是你创建了一个任务但没有等待它,所以立即调用CompleteAsync

这应该是一种更清洁的方法:

var task = ProcessServiceBusMessage(message);
await Task.WhenAny(task, Task.Delay(timeout));
await message.CompleteAsync();

答案 1 :(得分:0)

您是否要考虑使用Azure存储队列?

默认情况下,邮件被锁定30秒,因此可能存在冲突。在30秒取消发生之前,Service Bus可能会抛出Lock过期的异常