C#, RabbitMQ как запустить consumer в фоновом режиме

Структура моего решения

Структура моего решения

Проблема в том что, когда я из RunnerInput

StatisticOfTest statistic = new StatisticOfTest();
SolutionService solution = new SolutionService();

var factory = new ConnectionFactory
{
    HostName = "rabbitmq",
};

using (IConnection connection = factory.CreateConnection())
{
    using (IModel channel = connection.CreateModel())
    {
        using (IModel channel2 = connection.CreateModel())
        {
            channel.QueueDeclare("Input", exclusive: false, autoDelete: false, durable: false);
            channel2.QueueDeclare("Output", durable: false, exclusive: false, autoDelete: false, arguments: null);
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, eventArgs) =>
            {
                Console.WriteLine("Recieved Event");
                try
                {                  
                    var body = eventArgs.Body.ToArray();
                    var jsonStr = Encoding.UTF8.GetString(body);
                    SolutionAddModel solutionAdd = JsonConvert.DeserializeObject<SolutionAddModel>(jsonStr);                 
                    statistic = solution.Validating(solutionAdd);
                    
                    IBasicProperties props = channel.CreateBasicProperties();
                    props.MessageId = eventArgs.BasicProperties.MessageId;

                    if (String.IsNullOrEmpty(statistic.ErrorWhileCompiling))
                    {
                        statistic = solution.Create(solutionAdd);

                        jsonStr = JsonConvert.SerializeObject(statistic);
                        body =  Encoding.UTF8.GetBytes(jsonStr);

                        channel2.BasicPublish(exchange: "", routingKey: "Output", mandatory: false, props, body: body);
                        Console.WriteLine("OutputSend");
                    }
                    else
                    {
                        jsonStr = JsonConvert.SerializeObject(statistic);
                        body = Encoding.UTF8.GetBytes(jsonStr);

                        channel2.BasicPublish(exchange: "", routingKey: "Output", mandatory: false, props, body: body);
                        Console.WriteLine("OutputSend");
                    }
                    Console.WriteLine($"Message received: {jsonStr}");
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }                
            };
            channel.BasicConsume("Input", autoAck: true, consumer: consumer);
            Console.WriteLine(" Press [enter] to exit.(RunnerInput)");
            Console.ReadLine();
        }
    }
}

Отправляю сообщение в RunnerOutput

var serviceProvider = new ServiceCollection()
            .AddDbContext<ContestApiContext>(o =>
                o.UseNpgsql("Server = postgres; Port = 5432; Database = ContestApi; User Id = postgres; Password = 123;"))
            .BuildServiceProvider();

var context = serviceProvider.GetRequiredService<ContestApiContext>();
StatisticOfTest statistic;
OutputSaveService outputSaveService = new OutputSaveService(context);

var factory = new ConnectionFactory() 
{ 
    HostName = "rabbitmq",
};
using (var connection = factory.CreateConnection())
{
    using (var channel = connection.CreateModel())
    {
        channel.QueueDeclare(queue: "Output", durable: false, exclusive: false, autoDelete: false, arguments: null);

        Console.WriteLine(" [*] Waiting for messages.");
        var consumer = new EventingBasicConsumer(channel);

        consumer.Received += (model, ea) =>
        {
            Guid id = Guid.Parse(ea.BasicProperties.MessageId);

            var body = ea.Body.ToArray();
            var message = Encoding.UTF8.GetString(body);
            statistic = JsonConvert.DeserializeObject<StatisticOfTest>(message);

            outputSaveService.Save(statistic, id);
            Console.WriteLine(" [x] Received {0}", message);
        };
        channel.BasicConsume(queue: "Output", autoAck: true, consumer: consumer);
        Console.WriteLine(" Press [enter] to exit.(RunnerOutput)");
        Console.ReadLine();  ----------------Здесь зависает-----------
    }
}

Основной поток лочится из-за Console.Readline(), а без него Runner завершает свою работу.

Вот мой контроллер, если кому нужно

public class SolutionsController : Controller
    {
        private readonly IMessageSender _messageSender;
        private readonly ContestApiContext _context;

        public SolutionsController(IMessageSender messageSender, ContestApiContext context)
        {
            _messageSender = messageSender;
            _context = context;
        }

        [HttpPost]
        public async Task<IActionResult> CreateSolution([FromBody] SolutionAddModel solutionAdd)
        {
            StatisticOfTest statistic = new StatisticOfTest();
            var messageId = Guid.NewGuid();
            _messageSender.SendMessage(solutionAdd, messageId);
            if (_context.TestsStatistic.Any(u => u.Id == messageId))
            {            
                var recordInStatistic = _context.TestsStatistic.Where(_context => _context.Id == messageId).FirstOrDefault();
                statistic.Id = messageId;
                statistic.ErrorWhileCompiling = recordInStatistic.ErrorWhileCompiling;
                if (!String.IsNullOrEmpty(recordInStatistic.ErrorWhileCompiling))
                {                 
                    var recordsInSeTStatistic = _context.SetsStatistic.Where(_context => _context.Id == messageId).ToList();
                    
                    for(int i = 0; i < recordsInSeTStatistic.Count; i++)
                    {
                        statistic.SetsStatistic.Add(new CurrentSetStatistic
                        {
                            IdSet = recordsInSeTStatistic[i].TaskId,
                            ErrorWhileRunning = recordsInSeTStatistic[i].ErrorWhileRunning,
                            OutputEqualToExpected = recordsInSeTStatistic[i].OutputEqualToExpected,
                            Time = recordsInSeTStatistic[i].Time,
                            Memory = recordsInSeTStatistic[i].Memory,
                        });
                    }
                    return Ok(statistic);
                }
                return Ok(statistic);
            }

            return BadRequest("Нету такой записи в БД");
        }

    }

Насколько я понимаю, надо эти консольные приложения(Раннеры) запустить в фоновом режиме. Вопрос, как можно это сделать?


Ответы (0 шт):