RabbitMQ-如何以编程方式从消息队列接收消息?

时间:2018-07-20 20:14:01

标签: c# rabbitmq

这是我到目前为止所拥有的。我已经能够成功地将消息发布到队列中,并可以通过RabbitMQ的管理控制台看到它。

但是,当我尝试接收它时,它似乎根本没有触发回调函数。

这是相关的代码。

MessageQueue mq = new MessageQueue();

mq.Receive("task_queue", (model, ea) => {
    var message = Encoding.UTF8.GetString(ea.Body);
    System.Diagnostics.Debug.WriteLine(message);
});

这是我的Receive类中的MessageQueue函数:

    public void Receive(string queueName, EventHandler<BasicDeliverEventArgs> onReceived)
    {
        using (IConnection connection = GetConnection(myLocalhost))
        {
            using (IModel channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);

                // Don't dispatch a new message to a consumer until it has processed and acknowledged the previous one.
                channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);

                var consumer = new EventingBasicConsumer(channel); // non-blocking

                // Set the event to be executed when receiving a message
                consumer.Received += onReceived;

                // Register a consumer to listen to a specific queue. 
                channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
            }
        }
    }

当队列中有内容时尝试运行Receive函数时,没有任何内容输出到我的输出窗口。

有人可以帮我吗?

更新

我在Receive函数中获取了代码,并将其与调用它的代码放置在同一文件中。仍然没有运气。我认为这排除了范围界定问题。我还尝试将Received字段设置为实际的事件委托(而不是onReceive函数,并让该函数调用另一个我在其中放置了断点的函数。该函数从未被击中,这使我相信自己的完全不会调用事件委托回调。

我不知道为什么会这样。 RabbitMQ管理控制台向我显示该消息仍在队列中使用。我还尝试将队列重命名为其他名称,以确保没有其他幻像服务正在使用同一队列。没有雪茄。

更新2

我尝试提取两个using语句并在其中调用我的Receive函数,以保持范围,但这也不起作用。我什至将整个Receive块中的代码提取到一个主函数中,现在它甚至没有从队列中使用。

1 个答案:

答案 0 :(得分:1)

看看上面的代码,您会遇到一个非常简单的问题。

调用channel.BasicConsume后的瞬间,整个事物(连接/通道)超出范围,并通过using语句立即处置/破坏。

为防止这种情况发生,您需要在channel.BasicConsume之后立即进行无限循环,并且在关闭程序时当然要退出逻辑。

while (_isRunning & channel.IsOpen) {
    Thread.Sleep(1);
    // Other application logic here; e.g. periodically break out of the
    // loop to prevent unacknowledged messages from accumulating in the system
    // (if you don't, random effects will guarantee that they eventually build up)
}