2015-03-03 78 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

相關問題