DispatchConsumersAsync | Connection Factory | RabbitMQ | CSharp
- DispatchConsumersAsync | Connection Factory | RabbitMQ | CSharp
Essa propriedade é das versões antigas do pacote do Rabbit para o C#. Para analisar melhor a forma nova, consulte a documentação clicando aqui.
O que é DispatchConsumersAsync
factory.DispatchConsumersAsync = true;
Essa configuração diz ao RabbitMQ.Client:
“Vou usar consumidores assíncronos (
async/await), então despache as mensagens de forma compatível com Task.”
Ela muda a forma como o RabbitMQ chama o seu consumer internamente.
O que acontece sem isso (problema)
Por padrão (DispatchConsumersAsync = false):
- O RabbitMQ chama o consumer de forma sincrona
- Mesmo que você use
async/await, o código roda bloqueando thread - O
asyncvira praticamente umTask.Run().Wait()
Exemplo problemático ❌
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += async (sender, ea) =>
{
await ProcessarMensagemAsync(ea);
};
🔴 Se DispatchConsumersAsync = false:
- Pode causar deadlock
- Pode travar o consumer
- Pode atrasar ACKs
- Pode causar consumo lento e imprevisível
E o pior: não gera erro explícito.
O que muda quando é true
factory.DispatchConsumersAsync = true;
Agora:
- O RabbitMQ executa o consumer em um contexto assíncrono real
- O
awaitnão bloqueia a thread - O ACK acontece corretamente após o
await - Melhor uso de threads
- Mais estabilidade sob carga
Quando você DEVE usar
Você DEVE habilitar se:
-
Usa
AsyncEventingBasicConsumer -
Usa
async/awaitnoReceived -
Faz:
- I/O (HTTP, DB, cache)
- Delay
- Processamento assíncrono
📌 Hoje, quase todos os consumers modernos precisam disso.
Quando NÃO precisa
Você NÃO precisa se:
- Usa
EventingBasicConsumer - Seu código é 100% síncrono
- Não usa
async/await
Exemplo síncrono:
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (sender, ea) =>
{
ProcessarMensagem(ea);
};
Nesse caso:
DispatchConsumersAsync = false; // default
Diferença resumida (tabela)
| Situação | DispatchConsumersAsync |
|---|---|
| Consumer síncrono | ❌ Não precisa |
| Consumer async/await | ✅ Obrigatório |
| AsyncEventingBasicConsumer | ✅ Obrigatório |
| HTTP / DB async | ✅ Obrigatório |
| Alta concorrência | ✅ Recomendado |
Erro clássico em produção 🚨
“Meu consumer funciona em dev, mas trava em produção”
💥 Causa comum:
AsyncEventingBasicConsumerDispatchConsumersAsyncnão habilitado
Exemplo correto completo ✅
var factory = new ConnectionFactory
{
HostName = "localhost",
DispatchConsumersAsync = true
};
var connection = factory.CreateConnection();
var channel = connection.CreateModel();
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += async (sender, ea) =>
{
await ProcessarMensagemAsync(ea);
channel.BasicAck(ea.DeliveryTag, false);
};
channel.BasicConsume(
queue: "fila.exemplo",
autoAck: false,
consumer: consumer
);
Regra de ouro 🧠
Se existe um
awaitno consumer →DispatchConsumersAsync = true