【发布时间】:2014-09-29 17:07:30
【问题描述】:
我正在用 C# 设置一个标准的独立线程来监听 RabbitMQ。假设线程中监听的方法是这样的:
public void Listen()
{
using (var channel = connection.CreateModel())
{
var consumer = SetupQueues(channel);
while (true)
{
var ea = consumer.Queue.Dequeue(); // blocking call
handler.HandleMessage(channel, ea);
}
}
}
在 RabbitMQ 的 C# 客户端中优雅地停止消费消息的优雅方式是什么?请记住,我在 RabbitMQ 示例/文档或这些 SO 问题中没有发现任何用处:
- How to stop consuming message from selective queue - RabbitMQ
- How to pause and resume consumption gracefully in rabbitmq, pika python
- What is the best way to safely end a java application with running RabbitMQ consumers
这里的问题是consumer.Queue.Dequeue() 是一个阻塞调用。我已经尝试了这些选项:
呼叫
channel.BasicCancel(string tag)。这会导致阻塞调用中出现System.IO.EndOfStreamException。出于显而易见的原因,我不想将此异常用作控制流的一部分。调用
consumer.Queue.Dequeue(int millisecondsTimeout, out T result)并检查循环迭代之间的标志。这可以工作,但看起来很hacky。
我想让线程优雅地退出并清理我可能拥有的所有非托管资源,因此不会出现线程中止等情况。
感谢任何帮助。谢谢
【问题讨论】:
-
据我所知,没有“干净”的方法可以做到这一点。我个人使用超时方法——我的消费者线程检查一个标志,并据此决定做什么。这实际上似乎工作正常。本质上,应用程序的状态决定了队列是否应该被消费——消费者循环只是在它尝试消费之前检查它是否应该消费。
标签: c# rabbitmq messaging amqp consumer