如何正确处理SimpleRpcServer对象?

时间:2014-03-05 19:03:26

标签: c# rabbitmq dispose

我有一个RabbitMQ SimpleRpcServer,我想知道如何在完成后正确处理它。该模式有一个主循环,它阻塞直到它收到消息,处理消息,然后再次阻塞。这意味着为了打破循环,我必须发送一个特殊编码的消息,处理程序可以使用它来打破循环。

我已经读过RabbitMQ频道应该从创建它们的同一个线程中访问。如果这是真的(我找不到源代码),这是否意味着要配置我的SimpleRpcServer,我必须创建一个专门用于将关闭消息发送到主循环的新通道?

这是伪代码:

主循环(actual code here):

//I run this on a ThreadPool thread
foreach (var evt in m_subscription) //blocks until a message appears
{
    ProcessRequest(evt);
}

处理程序:

private void ProcessRequest(evt)
{
    if(evt.BasicProperties.ContentType == "close") //close flag
    {
        base.Close();
    }
    else
    {
        //process message
    }
}

处置代码(专门用于取消主循环创建新通道):

//I call this from the main thread
public void Dipose()
{
    var channel = new Channel();
    var props = new Properties("close"); //close flag
    channel.BasicPublish(queueName, props);
    channel.Dispose();
}

请注意,我遗漏了一些初始化和处理代码。我知道这段代码不会编译。

1 个答案:

答案 0 :(得分:1)

是的,你不应该在两个或多个线程之间共享通道,请阅读http://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v3.2.4/rabbitmq-dotnet-client-3.2.4-user-guide.pdf“2.10。不应在线程“

之间共享IModel

要关闭频道,您可以使用频道创建订阅线程,然后关闭主线程上的频道,如下所示:

初始化连接,频道等......

ConnectionFactory connection_factory = new ConnectionFactory();
        IConnection conn = null;
        IModel channel = null;
        Subscription sub = null;
        private void Connect()
            try
            {
                conn = connection_factory.CreateConnection();
                channel = conn.CreateModel();
                sub = new Subscription(channel, your_queue, true);
                StartSubscribeThread (sub);
….

创建你的主题:

 public void  StartSubscribeThread(Subscription sub)
 {
    var t = new Thread(() => InternalStartSubscriber(sub));
    t.Start();
 }



private void InternalStartSubscriber(Subscription sub)
{
   foreach (BasicDeliverEventArgs e in sub)
   {
    //Handle your messages 
   }
} 

最后:

private void Disconnet()
sub.Close();
channel.Close();
channel.Dispose();

通过这种方式,您可以避免创建另一个关闭第一个

的频道