Правильный способ инициализации фонового сервиса в ядре dot net - PullRequest
2 голосов
/ 30 октября 2019

У меня есть служба, которая должна подключиться к другой службе на startup. Другой сервис - брокер Rabbitmq.

Я слушаю какое-то событие из Rabbitmq, поэтому мне нужно, чтобы оно активировалось с самого начала приложения.

Мне нужно подключиться к двум различным VHost с, поэтомуМне нужно создать два соединения.

Проблема в том, что при запуске приложение постоянно создает соединения, пока сервер не выйдет из строя!

В управлении Rabbitmq я вижу много Connection иChannels созданы.

Я не могу выяснить, почему это происходит.

В общем, я хочу знать, как правильно подключаться к другим службам при запускемое приложение в ядре dotnet.

Я использую этот код для этого:

public void ConfigureServices(IServiceCollection services)
        {
            .....

            services.AddSingleton<RabbitConnectionService>();

            ...

            ActivatorUtilities.CreateInstance<RabbitConnectionService>(services.BuildServiceProvider());
        }

И в конструкторе RabbitConnectionService я подключаюсь к Rabbitmq.

public RabbitConnectionService(IConfiguration configuration)
        {   
            ServersMessageQueue = new MessageQueue(configuration.GetConnectionString("FirstVhost"), "First");
            ClientsMessageQueue = new MessageQueue(configuration.GetConnectionString("SecondVhost"), "Second");
        }

Класс сообщенияQueue:

public class MessageQueue
    {

        private IConnection connection;

        private string RabbitURI;
        private string ConnectionName;

        static Logger _logger = LogManager.GetCurrentClassLogger();

        public MessageQueue(string connectionUri, string connectionName)
        {
            ConnectionName = connectionName;
            RabbitURI = connectionUri;
            connection = CreateConnection();
        }


        private IConnection CreateConnection()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.Uri = new Uri(RabbitURI);
            factory.AutomaticRecoveryEnabled = true;
            factory.RequestedHeartbeat = 10;
            return factory.CreateConnection(ConnectionName);
        }

        public IModel CreateChannel()
        {
            return connection.CreateModel();
        }

        ...
    }

1 Ответ

0 голосов
/ 02 ноября 2019

Чтобы включить фоновую обработку, вам нужно создать класс, который реализует интерфейс IHostedService.

public interface IHostedService
{
    Task StartAsync(CancellationToken cancellationToken);
    Task StopAsync(CancellationToken cancellationToken);
}

Этот интерфейс получил два метода StartAsync и StopAsync. И вам необходимо зарегистрировать сервис, используя внедрение зависимостей, например:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<IHostedService, DemoService>();
    ...
}

Вместо реализации IHostedService вы можете наследовать от BackgroundService абстрактный класс и реализовывать абстрактный метод ExecuteAsync. Вот пример минимальной фоновой службы, которая отслеживает таблицу в SQL Server и отправляет электронные письма:

public class DemoService : BackgroundService
{
    private readonly ILogger<DemoService> _demoservicelogger;
    private readonly DemoContext _demoContext;
    private readonly IEmailService _emailService;
    public DemoService(ILogger<DemoService> demoservicelogger, 
        DemoContext demoContext, IEmailService emailService)
    {
        _demoservicelogger = demoservicelogger;
        _demoContext = demoContext;
        _emailService = emailService;
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _demoservicelogger.LogDebug("Demo Service is starting");
        stoppingToken.Register(() => _demoservicelogger.LogDebug("Demo Service is stopping."));
        while (!stoppingToken.IsCancellationRequested)
        {
            _demoservicelogger.LogDebug("Demo Service is running in background");
            var pendingEmailTasks = _demoContext.EmailTasks
                .Where(x => !x.IsEmailSent).AsEnumerable();
            await SendEmailsAsync(pendingEmailTasks);
            await Task.Delay(1000 * 60 * 5, stoppingToken);
        }
        _demoservicelogger.LogDebug("Demo service is stopping");
    }
}

Благодаря Иану Кемпу.

Refrence

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...