清理队列和连接 - 控制台应用程序在退出

时间:2016-04-26 20:40:36

标签: c# rabbitmq

在一个非常简单的控制台应用程序中使用RabbitMQ我遇到了一个问题,即控制台应用程序在执行结束时没有退出,而我认为可能是因为我和#39; m挂在RabbitMQ的东西上。那么究竟需要处理什么呢?我有一个类Queue类看起来像这样:

public class ManagementQueue : IDisposable
{
    private IConnection connection;
    private IModel channel;
    private string privateQueueName;
    private EventingBasicConsumer consumer;

    public event EventHandler SomeEvents;     

    public ManagementQueue()
    {
        var factory = new ConnectionFactory() 
        { 
            HostName = Properties.Settings.Default.RabbitMQServer,
            UserName = Properties.Settings.Default.RabbitMQUser,
            Password = Properties.Settings.Default.RabbitMQPassword
        };
        connection = factory.CreateConnection();
        channel = connection.CreateModel();

        privateQueueName = channel.QueueDeclare().QueueName;        

        channel.QueueDeclare(queue: Properties.Settings.Default.ManagementQueueName,
            durable: true,
            exclusive: false,
            autoDelete: false,
            arguments: null);

      channel.ExchangeDeclare(Properties.Settings.Default.BroadcastExchange, "fanout");       
        channel.ExchangeDeclare(Properties.Settings.Default.DirectExchange, "direct");          

        channel.QueueBind(privateQueueName,
            Properties.Settings.Default.DirectExchange,
            privateQueueName);

        channel.QueueBind(Properties.Settings.Default.ManagementQueueName,
            Properties.Settings.Default.DirectExchange,
            "fromManager");

        channel.BasicQos(0, 1, false);
    }

    public void StartListening()
    {
        consumer = new EventingBasicConsumer(channel);
        consumer.Received += ReceivedHandler;

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

    public void StopListening()
    {
        consumer.Received -= ReceivedHandler;
    }

    private void ReceivedHandler(object model, BasicDeliverEventArgs ea)
    {
        // Do some stuff...
    }

    public void SomeFunction()
    {
        // send out some message...
        var props = channel.CreateBasicProperties();
        props.ReplyTo = privateQueueName;

        channel.BasicPublish(exchange: Properties.Settings.Default.BroadcastExchange,
                 routingKey: "",
                 basicProperties: props,
                 body: null);
    }

    public void Dispose()
    {
        if (channel != null)
        {
            channel.Dispose();
            channel = null;
        }
        if (connection != null)
        {
            connection.Dispose();
            connection = null;
        }
    }
}

在控制台中我有类似的东西:

static void Main(string[] args)
{
   if (!args.Any())
   {
       // This works fine exiting here
       return;
   }
   var queue = new ManagementQueue();
   queue.SomeEvents += (o,e) => { // do something };
   queue.StartListening();
   queue.SomeFunction();

   while (!somecondition)
   {
       // do some other stuff
   }
   queue.StopListening();
   queue.Dispose();
   return;    // app should quit here, but doesn't???
}

我怀疑这可能与消费者有关,但似乎没有任何方法可以处理,关闭或断开它。不知道我在哪里显式创建任何新线程或任何紧密循环(除了while循环之外,但在条件计算结果为false时会退出)。

1 个答案:

答案 0 :(得分:1)

这是一篇非常古老的帖子,但看起来RabbitMQ在调用IModel上的Dispose时遇到了问题。您可能只想尝试处理连接并查看是否可以解决问题。

参考1:http://markmail.org/message/tqyiezrmixagtwa4#query:+page:1+mid:mhl5iw2gylwznd5o+state:results

参考2:http://rabbitmq.1065348.n5.nabble.com/IModel-Dispose-locks-if-called-during-ConnectionShutdown-event-tc22104.html

建议修复:

  

建议不要在IModel实例上调用dispose   ConnectionShutdown事件。我不得不重新编写代码来跟踪它是否存在   在连接中调用或不知道何时调用dispose。