有许多方法可以做到这一点。例如,您可以使用EventingBasicConsumer
与ManualResetEvent
一起使用,像这样(这仅用于演示目的 - 最好使用以下方法之一):
var factory = new ConnectionFactory();
using (var connection = factory.CreateConnection()) {
using (var channel = connection.CreateModel()) {
using (var signal = new ManualResetEvent(false)) {
var consumer = new EventingBasicConsumer(channel);
byte[] messageBody = null;
consumer.Received += (sender, args) => {
messageBody = args.Body;
signal.Set();
};
channel.BasicConsume("your.queue", false, consumer);
bool timeout = !signal.WaitOne(TimeSpan.FromSeconds(10));
channel.BasicCancel(consumer.ConsumerTag);
if (timeout) {
throw new Exception("timeout");
}
}
}
}
正如您在评论中所述 - 如果您希望在同一队列上接收多个消息,那么这并不是最佳方式。事实上,在任何情况下都不是最佳方式,我只是为了演示在库本身不提供超时支持的情况下如何使用ManualResetEvent
。
如果您正在进行RPC(远程过程调用,请求-响应) - 您可以在服务器端使用SimpleRpcServer
和SimpleRpcClient
。客户端将如下所示:
var client = new SimpleRpcClient(channel, "your.queue");
client.TimeoutMilliseconds = 10 * 1000;
client.TimedOut += (sender, args) => {
// do something on timeout
};
var reply = client.Call(myMessage); // will return reply or null if timeout reached
更加简单的方法:使用基本的Subscription
类(它内部使用相同的EventingBasicConsumer
,但支持超时,因此您无需自己实现),像这样:
var sub = new Subscription(channel, "your.queue");
BasicDeliverEventArgs reply;
if (!sub.Next(10 * 1000, out reply)) {
}