C# 在C中,如何处理队列中当前的所有RabbitMQ消息?

C# 在C中,如何处理队列中当前的所有RabbitMQ消息?,c#,.net,rabbitmq,C#,.net,Rabbitmq,给出了如何从队列中连续检索消息的示例: var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.QueueDeclare("hello", false, false, f

给出了如何从队列中连续检索消息的示例:

var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
    using (var channel = connection.CreateModel())
    {
        channel.QueueDeclare("hello", false, false, false, null);

        var consumer = new QueueingBasicConsumer(channel);
        channel.BasicConsume("hello", true, consumer);

        Console.WriteLine(" [*] Waiting for messages." +
                                 "To exit press CTRL+C");
        while (true)
        {
            var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);
        }
    }
}
我要做的是检索所有已放入队列的消息,然后停止

这里有两个例子可以解决我的问题

如果我在下午1点开始编写代码,我希望在下午1点之前处理队列中的所有消息。 或

如果我在13:00:00启动代码,代码运行需要10秒,我不介意它是否包含13:00:00到13:00:10之间放置在队列上的消息,只要队列一空它就停止。 我意识到我可能可以在我的消息中放置一个时间戳并检查它,或者我可以修改超时值,但我想知道是否有任何内置的方法可以正确地执行此操作

提前感谢。

您可以做什么:

一,。首先向消息对象添加时间戳

二,。如果时间戳无效,则拒绝消息。它是rabbitmq的集成功能

您可以做什么:

一,。首先向消息对象添加时间戳

二,。如果时间戳无效,则拒绝消息。它是rabbitmq的集成功能


从评论来看,RabbitMQ似乎不适用于批处理,因此它并不是为此目的而设计的

我还注意到,当测试DequeueNoWait方法时,或者尝试以零超时退出队列时,它们根本不起作用,只返回null

以下解决方案使用QueueDeclare获取现有消息的计数,不需要时间戳或黑客超时:

var factory = new ConnectionFactory { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
    using (var channel = connection.CreateModel())
    {
        var queueDeclareResponse = channel.QueueDeclare(Constants.QueueName, false, false, false, null);

        var consumer = new QueueingBasicConsumer(channel);
        channel.BasicConsume(Constants.QueueName, true, consumer);

        Console.WriteLine(" [*] Processing existing messages.");

        for (int i = 0; i < queueDeclareResponse.MessageCount; i++)
        {
            var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);
        }
        Console.WriteLine("Finished processing {0} messages.", queueDeclareResponse.MessageCount);
        Console.ReadLine();
    }
}

从评论来看,RabbitMQ似乎不适用于批处理,因此它并不是为此目的而设计的

我还注意到,当测试DequeueNoWait方法时,或者尝试以零超时退出队列时,它们根本不起作用,只返回null

以下解决方案使用QueueDeclare获取现有消息的计数,不需要时间戳或黑客超时:

var factory = new ConnectionFactory { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
    using (var channel = connection.CreateModel())
    {
        var queueDeclareResponse = channel.QueueDeclare(Constants.QueueName, false, false, false, null);

        var consumer = new QueueingBasicConsumer(channel);
        channel.BasicConsume(Constants.QueueName, true, consumer);

        Console.WriteLine(" [*] Processing existing messages.");

        for (int i = 0; i < queueDeclareResponse.MessageCount; i++)
        {
            var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);
        }
        Console.WriteLine("Finished processing {0} messages.", queueDeclareResponse.MessageCount);
        Console.ReadLine();
    }
}

从您的描述来看,排队似乎不是正确的工具,队列用于缓冲消息,以便生成消息的速度不会超过使用消息的速度,队列的设计目的不是在您决定处理消息之前保留消息。虽然RabitMQ确实支持持久队列,但这更适合容错。您应该始终立即处理队列中的消息。如果您想稍后对消息执行某些操作,请将其保存并从一些持久数据存储(如数据库)中检索。感谢您的评论,Ben。听起来MQ并不是解决您问题的解决方案。您可以创建一个名为processQueue的布尔变量,并将其设置为true。然后,进行处理并将变量更新为false。while循环随后将更改为:whileprocessQueue{//…},谢谢Praval。我会考虑MQ的另一种方法。我如何知道何时将变量设置为false?根据您的描述,似乎排队不是正确的工具,队列用于缓冲消息,以便生成消息的速度不会快于使用消息的速度,队列的设计目的是在您决定处理消息之前保持消息。虽然RabitMQ确实支持持久队列,但这更适合容错。您应该始终立即处理队列中的消息。如果您想稍后对消息执行某些操作,请将其保存并从一些持久数据存储(如数据库)中检索。感谢您的评论,Ben。听起来MQ并不是解决您问题的解决方案。您可以创建一个名为processQueue的布尔变量,并将其设置为true。然后,进行处理并将变量更新为false。while循环随后将更改为:whileprocessQueue{//…},谢谢Praval。我会考虑MQ的另一种方法。我怎么知道何时将变量设置为false?谢谢你的回答,EvilFonti。在我的问题中,我确实说过,我意识到我可能可以在我的消息中放置一个时间戳并检查它,或者我可以修改超时值,但我想知道是否有任何内置的方法可以正确地做到这一点。但是出于兴趣,我们使用什么方法来获取使用索引的元素呢?非常抱歉,我以为我在Rabbitmq中使用了索引来访问消息可能在MSMQ中就是这样,但我不知道了。。。。这是不可能的,但是你可以拒绝它->我编辑了答案。如果在应用程序启动后一段时间内没有消息发送,这个解决方案意味着必须等待超时。我猜这意味着需要设置一个很短的超时,但足够长的时间来检索现有消息。您的意思是因为:请注意,RabbitMQ不注意阻止同一消费者再次获取消息?我会在拒绝后停止或暂停退出队列循环,直到您希望再次获取队列的所有消息。Th
此时,您将在队列中的特定时刻接收所有消息。您可以使用Dequeueint毫秒计时、out object result或DequeueNoWaitobject defaultValue。谢谢你的回答,艾维芳蒂。在我的问题中,我确实说过,我意识到我可能可以在我的消息中放置一个时间戳并检查它,或者我可以修改超时值,但我想知道是否有任何内置的方法可以正确地做到这一点。但是出于兴趣,我们使用什么方法来获取使用索引的元素呢?非常抱歉,我以为我在Rabbitmq中使用了索引来访问消息可能在MSMQ中就是这样,但我不知道了。。。。这是不可能的,但是你可以拒绝它->我编辑了答案。如果在应用程序启动后一段时间内没有消息发送,这个解决方案意味着必须等待超时。我猜这意味着需要设置一个很短的超时,但足够长的时间来检索现有消息。您的意思是因为:请注意,RabbitMQ不注意阻止同一消费者再次获取消息?我会在拒绝后停止或暂停退出队列循环,直到您希望再次获取队列的所有消息。这样,您将在队列中的特定时刻接收所有消息。您可以使用Dequeueint毫秒计时、out object result或DequeueNoWaitobject defaultValue。不要使用QueueingBasicConsumer它没有内置恢复,使用EventingConsumer不要使用QueueingBasicConsumer它没有内置恢复,使用EventingConsumer