2015-03-03 81 views
1

我使用RabbitMQ(.Net客户端库)将WebAPI中的XML消息发布到队列中。如果发布的消息被成功持久保存到磁盘上,则需要发送状态码200,否则应返回代码400。 RabbitMQ客户端库提供了两个单独的事件来发送ACK或NACK事件,指示消息是否已保存。所以我的发布函数需要等待两个事件句柄中的任何一个被调用,然后才返回http响应。根据调用哪个事件处理函数的函数返回值

我该如何做到这一点?

阿比控制器动作

[HttpPost] 
public HttpResponseMessage SendSomething() 
{ 
    ... 
    bool success = _publisher.Publish(bytes); 
    if(success) // Send status 200 
    else // Send status 400 
    ... 
} 

消息发布代码

public bool Publish(byte[] data) 
{ 
    .. 
    channel.BasicAcks += OnAck; 
    channel.BasicNacks += OnNack; 
    channel.BasicPublish("", "test", null, data); 
    .. 
    // Depending on if OnAck or OnNack is called I need to return true or false 
    return ?? 
} 

private void OnNack(IModel model, BasicNackEventArgs args) 
{ 
    ... 
} 

private void OnAck(IModel model, BasicAckEventArgs args) 
{ 
    ... 
} 

回答

3

如果我没有理解错的,你需要变换基于异步回调例程转换为同步。天真的回答是睡觉的线程,并等待事情发生:

public bool Publish(byte[] data) 
{ 
    //.. 
    bool? response = null; 
    channel.BasicAcks += (model, args) => response = true; 
    channel.BasicNacks += (model, args) => response = false; 
    channel.BasicPublish("", "test", null, data); 

    while (response == null) 
     Thread.Sleep(300); 

    return response.Value; 
} 

但是,这意味着你的反应时间总是为300ms的倍数,你必须执行超时逻辑硬盘的方式的问题。更好的答案可能是使用ManualResetEvent。这使您的回调,只要已接收到响应通知阻塞的线程,通过“设置”事件:

public bool Publish(byte[] data) 
{ 
    //.. 
    bool successful = false; 
    var responseReceivedEvent = new ManualResetEvent(false); 

    channel.BasicAcks += (model, args) => 
    { 
     successful = true; 
     responseReceivedEvent.Set(); 
    }; 
    channel.BasicNacks += (model, args) => 
    { 
     successful = false; 
     responseReceivedEvent.Set(); 
    }; 
    channel.BasicPublish("", "test", null, data); 

    responseReceivedEvent.WaitOne(); 
    return successful; 
} 

在这两种情况下,你可以(或应该)实施某种形式的超时/重试逻辑,除非RabbitMQ为你做这个。在最后一个例子中,您可以使用WaitOne(int)WaitOne(TimeSpan)超载ManualResetEvent.WaitOne()

+0

这工作完美。我已经在玩AutoResetEvent,但看不到整个画面。我喜欢你使用lamda表达。谢谢! :) – maulik13 2015-03-03 11:48:07

相关问题