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("Нету такой записи в БД");
}
}
Насколько я понимаю, надо эти консольные приложения(Раннеры) запустить в фоновом режиме. Вопрос, как можно это сделать?
