C# RabbitMQ异步支持

C# RabbitMQ异步支持,c#,asynchronous,rabbitmq,C#,Asynchronous,Rabbitmq,RabbitMQ.NET客户端是否具有任何类型的异步支持?我希望能够异步连接和使用消息,但到目前为止还没有找到一种方法 (对于消费消息,我可以使用EventingBasicConsumer,但这不是一个完整的解决方案。) 下面是我目前如何使用RabbitMQ的一个示例(代码取自我的博客): 目前RabbitMQ.NET客户端没有内置的异步/等待支持。兔子支持使用AsyncEventingBasicConsumer类向异步消息处理程序发送消息。它的工作原理类似于事件基本消费者,但允许您注册一个返回

RabbitMQ.NET客户端是否具有任何类型的异步支持?我希望能够异步连接和使用消息,但到目前为止还没有找到一种方法

(对于消费消息,我可以使用EventingBasicConsumer,但这不是一个完整的解决方案。)

下面是我目前如何使用RabbitMQ的一个示例(代码取自我的博客):


目前RabbitMQ.NET客户端没有内置的异步/等待支持。兔子支持使用
AsyncEventingBasicConsumer
类向异步消息处理程序发送消息。它的工作原理类似于
事件基本消费者
,但允许您注册一个返回
任务
的回调。回调被调度到,RabbitMQ客户端等待返回的
任务

var factory = new ConnectionFactory
{
    HostName = "localhost",
    DispatchConsumersAsync = true
};

using(var connection = cf.CreateConnection())
{
    using(var channel = conn.CreateModel())
    {
        channel.QueueDeclare("testqueue", true, false, false, null);

        var consumer = new AsyncEventingBasicConsumer(model);

        consumer.Received += async (o, a) =>
        {
            Console.WriteLine("Message Get" + a.DeliveryTag);
            await Task.Yield();
        };
    }

    Console.ReadLine();
}

要总结当前的
async
/
TPL
支持:

  • 正如@paul turner提到的,现在有了一个
    AsyncEventingBasicConsumer
    ,您可以为它注册事件并返回一个
    任务
  • 还有一个可以覆盖虚拟方法(如
    HandleBasicDeliver
    )并返回
    任务的方法。原始PR(看起来它也是在5.0中引入的?)
  • 根据以上PR和的最后评论,看起来他们正在开发一个全新的.NET客户端,该客户端将更全面地支持
    async
    操作,但我没有看到任何与此相关的具体链接

AsyncEventingBasicConsumer
,它所做的就是在收到消息时等待您的异步“事件处理程序”。这是这里唯一一个异步的东西。通常你不会从中获得任何利润,因为你只有一个“处理者”。消息仍在逐个处理。它们是同步处理的!此外,由于等待是在使用者内部完成的,所以您将失去对异常处理的控制

让我猜,异步消息处理意味着某种程度的并行性

我最终使用的是来自TPL数据流的
ActionBlock
<代码>操作块
运行您配置的任务,管理等待和并行。因为它是在任务上操作的,而不是在线程上操作的,所以只要它们是真正异步的,它就可以用更少的资源进行管理

  • 常规
    EventingBasicConsumer
    调用
    actionBlock.Post(某物)
  • 对于并行处理,您需要在
    ack
    model.BasicQos(0,N,true)之前通知RMQ向您发送N条消息
  • ActionBlock具有带有
    MaxDegreeOfParallelism
    属性的选项,该属性也需要设置为N
  • ActionBlock运行
    异步任务
    s,该任务接收消费者先前发布的数据。任务不应抛出,因为ActionBlock会停止对异常的所有处理
  • 小心传递
    CancellationToken
    并正确等待ActionBlock完成所有正在运行的任务:
    ActionBlock.Complete();等待动作块完成

  • 你能再具体一点吗?在这种情况下,“异步”是什么意思?你想完成什么?异步/等待。。。因此,我正在寻找可以等待并返回任务的等价物,如System.IO,例如ConnectAsync()、ReadAsync()等。我无法确定添加了哪个版本,但是相关的提交是从2017年2月开始的。似乎从5.0.0-pre3开始提供。@Gigi我们对Producer有异步支持吗?@Pingpong我不知道。它对你有用吗?您不需要将
    DispatchConsumersAsync
    标志设置为true吗?
    var factory = new ConnectionFactory
    {
        HostName = "localhost",
        DispatchConsumersAsync = true
    };
    
    using(var connection = cf.CreateConnection())
    {
        using(var channel = conn.CreateModel())
        {
            channel.QueueDeclare("testqueue", true, false, false, null);
    
            var consumer = new AsyncEventingBasicConsumer(model);
    
            consumer.Received += async (o, a) =>
            {
                Console.WriteLine("Message Get" + a.DeliveryTag);
                await Task.Yield();
            };
        }
    
        Console.ReadLine();
    }