title: Setup Rabbitmq consumer in dotnet core by timed background task
body: <p>I try to setup the rabbitmq consumer by <strong>timed background task</strong>, however, it's not always consuming message correctly. <strong>It seems to get message from queue, but does not log the received message correctly.</strong> This seems to be very weird. I guess it's somehow related to the event handler receiving message not executed properly, but I just cannot figure out why.</p>
  
  <p>I do the timed background task as discussed in <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&amp;tabs=visual-studio#backgroundservice-base-class" rel="nofollow noreferrer">Background tasks with hosted services in ASP.NET Core</a> because I want to avoid having a long lived connection. I feel it's more safe to create new connections to queue when needed.</p>
  
  <p>However, when using background service with long lived connection, everything actually works fine so far.</p>
  
  <p>Can someone tell me what's wrong about the following code?</p>
  
  <pre><code>// consumer part
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading;
  using System.Threading.Tasks;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Hosting;
  using Microsoft.Extensions.Logging;
  using Microsoft.Extensions.Options;
  using RabbitMQ.Client;
  using RabbitMQ.Client.Events;
  
  namespace play_mq
  {
      public class Program
      {
          public static void Main(string[] args)
          {
              CreateHostBuilder(args).Build().Run();
          }
  
          public static IHostBuilder CreateHostBuilder(string[] args) =&gt;
              Host.CreateDefaultBuilder(args)
                  .ConfigureLogging(logging =&gt;
                  {
                      logging.AddConsole();
                  })
                  .ConfigureServices(services =&gt;
                  {
                      services.AddHostedService&lt;MessageListener&gt;();
                  });
      }
  
      public class MessageListener : IHostedService, IDisposable
      {
          private readonly IOptions&lt;RabbitOptions&gt; _rabbitOptions;
          private readonly ILogger&lt;MessageListener&gt; _logger;
          private Timer _timer;
          private int executionCount = 0;
  
          public MessageListener(ILogger&lt;MessageListener&gt; logger, IOptions&lt;RabbitOptions&gt; rabbitOptions)
          {
              _logger = logger;
              _rabbitOptions = rabbitOptions;
          }
  
          public Task StartAsync(CancellationToken cancellationToken)
          {
              _timer = new Timer(DoWork, null, TimeSpan.Zero,
                  TimeSpan.FromSeconds(5));
  
              return Task.CompletedTask;
  
          }
  
          private void DoWork(object state)
          {
              var count = Interlocked.Increment(ref executionCount);
  
              _logger.LogInformation(
                  "MessageListener is working. Count: {Count}", count);
  
              var factory = new ConnectionFactory()
              {
                  HostName = "localhost"
              };
  
              using (var connection = factory.CreateConnection())
              using (var channel = connection.CreateModel())
              {
                  channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
                  var consumer = new EventingBasicConsumer(channel);
                  consumer.Received += (model, ea) =&gt;
                  {
                      var body = ea.Body;
                      var message = Encoding.UTF8.GetString(body.ToArray());
                      _logger.LogInformation($"consume {message}");
                  };
                  channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
              }
          }
  
          public Task StopAsync(CancellationToken cancellationToken)
          {
              _logger.LogInformation("MessageListener is stopping.");
  
              _timer?.Change(Timeout.Infinite, 0);
  
              return Task.CompletedTask;
          }
  
          public void Dispose()
          {
              _timer?.Dispose();
          }
      }
  
  }
  </code></pre>
  
  <pre><code>// Sender comes from official example
  using System;
  using RabbitMQ.Client;
  using System.Text;
  
  namespace ConsoleMq
  {
      class Send
      {
          public static void Main()
          {
              var factory = new ConnectionFactory() { HostName = "localhost", Port = 14000 };
              using (var connection = factory.CreateConnection())
              using (var channel = connection.CreateModel())
              {
                  channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
  
                  string message = "Hello World!";
                  var body = Encoding.UTF8.GetBytes(message);
  
                  channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);
                  Console.WriteLine(" [x] Sent {0}", message);
              }
  
              Console.WriteLine(" Press [enter] to exit.");
              Console.ReadLine();
          }
      }
  }
  </code></pre>