RabbitMQ BasicConsume и управляемые событиями проблемы, связанные с Console.ReadLine()

Приведенная ниже программа в основном представляет собой программу из программы Receiver/Worker из учебника по C# Rabbit MQ здесь: https://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html (с добавленным счетчиком).

Есть две или три вещи, которые поставили меня в тупик:

1) Если я закомментирую "Console.ReadLine()", он получит сообщения из очереди и отобразит:

Start 
Press [enter] to exit. 
My End - CountMessagesProcessed=0

Первые несколько раз, когда я тестировал, я не мог понять, что происходит.

2) Эта строка никогда не отображается в выходных данных: Console.WriteLine("Нажмите [enter] для выхода.");. Предположительно, потому что это перед "Console.ReadLine();", но почему? Каково взаимодействие между событием ReadLine и BasicConsumer?

3) На странице MQ Tutorial говорится, что для остановки процесса "слушателя" нужно использовать CNTL-C, но я обнаружил, что нажатие клавиши enter работает одинаково хорошо.

Я уже писал слушатели для MQSeries с многопоточностью, что мне может понравиться лучше, но я просто пытался понять основные предоставленные учебники.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace RabbitMQReceiver
{
    class Receive
    {
        public static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            var myQueuename = "MyQueueName1";
            Console.WriteLine("My Start");


            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: myQueuename,
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                var consumer = new EventingBasicConsumer(channel);
                int countMessagesProcessed = 0;

                // this chunk of code is passed as parm/variable to BasicConsume Method below to process each item pulled of the Queue 
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    countMessagesProcessed++;
                    Console.WriteLine(" [x] Received {0}", message);
                }

                channel.BasicConsume(queue: myQueuename,
                                     noAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");  // this line never shows up in output 
                Console.ReadLine();    // if this line is commented out the message are consumed, but no Console.WriteLines appear at all. 
                Console.WriteLine("My End - CountMessagesProcessed=" + countMessagesProcessed);

            }
        }
    }
}

2 ответа

Console.ReadLine() останавливает выполнение вашей программы в этот момент в ожидании ввода, что позволяет тем нитям, которые RabbitMQ использует для запуска в это время. Закомментировано, что выполнение программы завершается и завершается, включая потоки RabbitMQ.

Да, вы можете напечатать что угодно, и это остановит выполнение программы; как только вы нажмете клавишу, выполнение программы продолжится и будет выполняться до конца.

Вместо использования Console.ReadLine() используйте Thread.Sleep(Timeout.Infinite), чтобы ваша основная программа (или основной поток) не завершилась сразу. У меня это сработало и для запуска netcore rabbitmq в Linux.

Другие вопросы по тегам