RabbitMQ仅处理50条消息然后阻止

时间:2014-10-31 14:19:09

标签: c# multithreading rabbitmq

我在.net中使用RabbitMQ,当我在队列中丢弃100条消息时,我发现了一个奇怪的问题。它处理大约50条消息,然后Dequeue()方法就会挂起。如果我重新启动该服务,它将处理剩余的项目。

编辑:它正在处理队列的50%。当我添加1000条消息时,它只处理500条。即使是单线程

我在这里缺少什么?

    private void InitializeAgent() {
        var agentFactory = new ConnectionFactory() { HostName = "localhost" };
        agentConnection = agentFactory.CreateConnection();
        agentChannel = agentConnection.CreateModel();
        var ok = agentChannel.QueueDeclare(GetType().Name, true, false, false, null);
        consumer = new QueueingBasicConsumer(agentChannel);
        agentChannel.BasicConsume(GetType().Name, false, consumer);
    }

    public void DequeueMessages() {
        ThreadPool.SetMaxThreads(200, 200);
        ThreadPool.SetMinThreads(200, 200);
        var ea = consumer.Queue.Dequeue();
        ThreadPool.QueueUserWorkItem(ProcessWorkInThread, ea);
    }

    public void AgentTask() {
        var instance = factory.GetInstance(threadItem);

        while (true) 
            DequeueMessages();
    }

    private void ProcessWorkInThread(object state) {
         var ea = state as BasicDeliverEventArgs;

         var message = Encoding.UTF8.GetString(ea.Body);

         var settings = new JsonSerializerSettings();
         settings.ContractResolver = new DefaultContractResolver() { DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public };
         var item = JsonConvert.DeserializeObject<TEntity>(message, settings);

         Thread.Sleep(10000) //simulate work
         lock (agentChannel)             
             agentChannel.BasicAck(ea.DeliveryTag, false);            
     }

1 个答案:

答案 0 :(得分:0)

这必须是使用3.4.0的.NET客户端版本问题,以下代码按预期工作。

static readonly ConnectionFactory Factory = new ConnectionFactory { HostName = "localhost" };
static readonly IConnection Connection = Factory.CreateConnection();
static QueueingBasicConsumer consumer;
static IModel agentChannel;

static CancellationTokenSource _tokenSource;

static void Main(string[] args)
{
    _tokenSource = new CancellationTokenSource();

    const string queueName = "testQueue";
    agentChannel = Connection.CreateModel();
    agentChannel.QueueDeclare(queueName, true, false, false, null);
    agentChannel.QueueBind(queueName, "testExchange", "");

    consumer = new QueueingBasicConsumer(agentChannel);
    agentChannel.BasicConsume(queueName, false, consumer);

    while (!_tokenSource.Token.IsCancellationRequested)
    {
        DequeueMessages();
    }
    Console.ReadLine();
    _tokenSource.Cancel();
}

static void DequeueMessages()
{
    ThreadPool.SetMaxThreads(200, 200);
    ThreadPool.SetMinThreads(200, 200);
    var ea = consumer.Queue.Dequeue();
    ThreadPool.QueueUserWorkItem(ProcessWorkInThread, ea);
}

static void ProcessWorkInThread(object state)
{
    var ea = state as BasicDeliverEventArgs;

    var message = Encoding.UTF8.GetString(ea.Body);

    var settings = new JsonSerializerSettings();
    settings.ContractResolver = new DefaultContractResolver()
    {
        DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public
    };
    var item = JsonConvert.DeserializeObject<string>(message, settings);
    Console.WriteLine(item);
    Thread.Sleep(10000); //simulate work
    lock (agentChannel)
        agentChannel.BasicAck(ea.DeliveryTag, false);
}