消费Azure队列时Web API无法启动及队列消息接收异常问题问询
问题原因分析
第一版代码无法启动Web API的根因
ConfigureServices是ASP.NET Core的服务注册阶段,必须执行完成后才会继续启动Web服务器、加载Swagger等组件。你在代码的finally块中添加了Console.ReadKey(),直接阻塞了整个启动流程,程序一直停在等待用户输入的状态,自然无法启动Web服务。
同时长驻的队列监听逻辑本身就不应该写在服务注册阶段,会影响正常的服务启动流程。
第二版代码无法接收消息的根因
- 队列连接刚注册就被销毁:你在
DoWork方法的finally块中执行了queueClient.CloseAsync(),等于刚注册完消息处理器就立刻关闭了队列连接,没有时间接收消息。 - 重复初始化无意义:设置了每5秒执行一次
DoWork,每次都会新建队列客户端实例,旧实例还没工作就被销毁,完全是无效操作。 - 存在语法错误:
new QueueClient("QueueConnectionString", "QueueName"]这行右括号写成了方括号,编译阶段就会报错。
正确实现方案
队列监听只需要在后台服务启动时初始化一次,保持长连接即可,不会影响Web API的控制器、Swagger等正常功能:
- 实现队列监听后台服务
public class QueueHostedService : IHostedService, IDisposable { private QueueClient _queueClient; private readonly IConfiguration _configuration; public QueueHostedService(IConfiguration configuration) { _configuration = configuration; } public async Task StartAsync(CancellationToken stoppingToken) { // 服务启动时仅初始化一次队列客户端 _queueClient = new QueueClient(_configuration["BusConnectionString"], _configuration["QueueName"]); var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false }; // 注册消息处理器,后台自动监听,不会阻塞主线程 _queueClient.RegisterMessageHandler(ReceiveMessagesAsync, messageHandlerOptions); await Task.CompletedTask; } public async Task StopAsync(CancellationToken stoppingToken) { // 服务停止时再关闭队列连接 if (_queueClient != null) { await _queueClient.CloseAsync(); } } public void Dispose() { _queueClient?.CloseAsync().Wait(); } private async Task ReceiveMessagesAsync(Message message, CancellationToken token) { Console.WriteLine($"Received message: {Encoding.UTF8.GetString(message.Body)}"); await _queueClient.CompleteAsync(message.SystemProperties.LockToken); } private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs) { Console.WriteLine(exceptionReceivedEventArgs.Exception); return Task.CompletedTask; } }
- 在
ConfigureServices中注册服务
public void ConfigureServices(IServiceCollection services) { // 保留原有Web API相关服务注册 services.AddControllers(); services.AddSwaggerGen(); // 注册队列监听后台服务 services.AddHostedService<QueueHostedService>(); }
这样修改后,Web API可以正常启动、Swagger可以正常访问,同时队列也会保持长连接监听消息。
内容的提问来源于stack exchange,提问作者TheBoubou
相关产品推荐
相关产品推荐

