为何在Azure ServiceBus消息处理中需要或使用CancellationToken?
理解CancellationToken在ServiceBus调度/取消操作中的作用
你现在用的CancelScheduledMessageAsync(sequenceNumber)和CancellationToken完全是两回事,别搞混了:
CancelScheduledMessageAsync的作用:给ServiceBus服务器发指令,删除你之前已经提交成功的待入队调度消息——操作对象是服务器端已存在的调度任务。CancellationToken的作用:控制客户端发起的API调用过程本身——比如调用ScheduleMessageAsync或CancelScheduledMessageAsync时,如果需要中途终止请求(比如用户点了取消按钮、请求超时、应用要关闭),用这个token可以让客户端停止等待服务器响应,直接抛出OperationCanceledException,避免客户端一直挂着占用资源。
举两个实际场景:
- 调用
ScheduleMessageAsync时网络突然卡住,客户端一直在等服务器回复。如果有CancellationToken(比如设置了10秒超时),到时间后客户端会直接终止请求,不用傻等;但如果服务器已经在卡住前收到了调度请求,那这条消息还是会按时入队,你得再用CancelScheduledMessageAsync去删它。 - 在桌面APP里做“调度消息”功能,用户点了调度按钮后又立刻点了取消,这时候用CancellationToken可以终止正在进行的
ScheduleMessageAsync请求(如果还没完成的话),避免不必要的网络请求。
要不要用CancellationToken?
- 如果你的代码是在桌面应用、WebAPI这类需要响应用户操作或有超时需求的场景,一定要加,这是.NET异步编程的最佳实践。可以结合
CancellationTokenSource设置超时,或者绑定用户的取消操作。 - 如果是简单的后台定时任务,没有取消需求,也可以不用,但加上也没坏处。
带CancellationToken的示例代码
// 创建一个带10秒超时的CancellationTokenSource var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); try { ServiceBusSender sender = client.CreateSender(queue); ServiceBusMessage message = new ServiceBusMessage(messageBody); // 传入CancellationToken var sequenceNumber = await sender.ScheduleMessageAsync(message, scheduledEnqueueTimeUtc, cts.Token); // 取消调度消息时也可以传入token await sender.CancelScheduledMessageAsync(sequenceNumber, cts.Token); } catch (OperationCanceledException) { // 处理请求被取消的情况:比如超时、用户主动取消 Console.WriteLine("请求已被取消"); }
内容的提问来源于stack exchange,提问作者chuckd
相关产品推荐
相关产品推荐

