c# - 在 RabbitMQ 的 C# 客户端中优雅地停止消息消费的优雅方法是什么?

标签 c# rabbitmq messaging amqp consumer

我正在设置一个标准的独立线程,用于在 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 问题中没有发现任何用处:

这里的问题是 consumer.Queue.Dequeue() 是一个阻塞调用。我尝试了这些选项:

  • 调用 channel.BasicCancel(string tag)。这会在阻塞调用中导致 System.IO.EndOfStreamException。出于显而易见的原因,我不想将此异常用作控制流的一部分。

  • 调用 consumer.Queue.Dequeue(int millisecondsTimeout, out T result) 并在循环迭代之间检查标志。这可以工作,但看起来很老套。

我想让线程正常退出并清理我可能拥有的任何非托管资源,这样就不会出现线程中止等情况。

感谢任何帮助。谢谢

最佳答案

带有超时和标志的 DeQueue 是实现它的方法。这是一种非常常见的模式,这就是为什么许多阻塞调用都带有启用超时的版本。

或者,抛出一个(已知的)异常对控制流来说不一定是坏事。优雅地关闭可能意味着实际捕获异常,评论“这是在请求 channel 关闭时抛出的”,然后干净地返回。这就是 TPL 的一部分如何与 CancellationToken 一起工作。

关于c# - 在 RabbitMQ 的 C# 客户端中优雅地停止消息消费的优雅方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26105228/

相关文章:

c# - 如何在 Javascript 中显示 C# 模型列表的某一方面?

c# - CopyListBoxItem 从一个 ListBox 到另一个

rabbitmq - 在rabbitmq中创建集群时出错

java - 一个队列上的多个消费者 RabbitMQ - Java

java - 在 Java 中寻找简单的持久消息缓冲区

php - 从 PHP 的 mysql_query 转换成 Python?

c# - 将一系列事件转换为更细粒度的值序列

C# 正则表达式从输入中提取组

java - jgroup 是否使用校验和来使 UDP 变得可靠?

java - JMS - 消息选择器如何与多个队列和主题消费者一起工作?