2016-10-20 2 views
0

Я изучаю RabbitMq с .NET. Согласно tutorial, простейшая реализация потребителя выглядит следующим образом:C# RabbitMq: метод рефакторинга нарушает функциональность?

public class Receive 
{ 
    public static void Main() 
    { 
    var factory = new ConnectionFactory() { HostName = "localhost" }; 
    using(var connection = factory.CreateConnection()) 
    using(var channel = connection.CreateModel()) 
    { 
     channel.QueueDeclare(queue: "hello", 
          durable: false, 
          exclusive: false, 
          autoDelete: false, 
          arguments: null); 

     var consumer = new EventingBasicConsumer(channel); 
     consumer.Received += (model, ea) => 
     { 
      var body = ea.Body; 
      var message = Encoding.UTF8.GetString(body); 
      Console.WriteLine(" [x] Received {0}", message); 
     }; 
     channel.BasicConsume(queue: "hello", 
          noAck: true, 
          consumer: consumer); 

     Console.WriteLine(" Press [enter] to exit."); 
     Console.ReadLine(); 
    } 
    } 
} 

И это работает правильно. Тем не менее, я хотел реорганизовать его: пусть определить функциональность приемника в отдельном методе. Он выглядит следующим образом:

public class Recieve 
{ 
    private ConnectionFactory factory; 
    public void ConsumeSimpleMessage(string queueName = "default") 
    { 
     using(var connection = factory.CreateConnection()) 
     { 
      using(var channel = connection.CreateModel()) 
      { 
       channel.QueueDeclare(queue: queueName, durable: false, 
        exclusive: false, autoDelete: false, arguments: null); 
       var consumer = new EventingBasicConsumer(channel); 
       consumer.Received += (model, ea) => 
       { 
        var body = ea.Body; 
        var message = Encoding.UTF8.GetString(body); 
        Console.WriteLine(message); 
       }; 

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


    } 
    public Recieve(string hostName = "localhost") 
    { 
     factory = new ConnectionFactory() { HostName = hostName }; 
    } 
} 

И когда я пытаюсь вызвать этот метод Main():

class Program 
{ 
    static void Main(string[] args) 
    { 
     Recieve reciever = new Recieve(); 

     reciever.ConsumeSimpleMessage(); 

     Console.ReadLine(); 
    } 
} 

здесь не работает. Он ничего не показывает. Однако сообщения будут удалены, что означает, что они были получены. Почему это происходит? Есть ли что-нибудь, что я не знал о передаче событий?

+0

Можете ли вы проверить свою очередь с ошибкой/ошибкой и посмотреть, есть ли там что-нибудь. – MindingData

+0

Должно ли ваше имя очереди быть приветствием? – Joe

ответ

2

Попробуйте просмотреть, не работает ли это, или если вы хотите использовать оператор using, сохраните код Console.Read() внутри инструкции using и посмотрите, работает ли это. Вы можете сохранить соединение и канал открытым и не закрывать его вручную.

Если вы действительно хотите отлаживать, вы можете поставить точку останова на потребителя. Получите доступ и посмотрите, не видно ли сообщение, оставленное без присмотра. Таким образом, вы знаете, когда сообщение будет удалено.

Также я рекомендую использовать трассировщик для rabbitmq, поскольку он регистрирует все сообщения, поступающие на сервер, что позволяет легко отслеживать.

+0

работает точно после размещения Console.Read() внутри операторов using. Я нашел краткое объяснение, почему он работает здесь http://stackoverflow.com/questions/37192346/rabbitmq-basicconsume-and-event-driven-issues-relating-to-console-readline, но есть ли какое-либо глубокое полное объяснение , почему я должен вызвать Console.Read() или Console.ReadLine(), чтобы он работал? –

+0

Я думаю, что когда вы используете утверждения, объекты становятся доступными, вы можете попробовать не использовать инструкцию «using» для создания соединения и каналов. Это может помочь. И поскольку у вас небольшое приложение, соединение и канал, если они открыты, не создают большого количества трафика. –

Смежные вопросы