在点网核心中初始化后台服务的正确方法

问题描述 投票:2回答:1

我有一个服务,需要在startup处连接到另一个服务。另一个服务是Rabbitmq经纪人。

我正在监听Rabbitmq中的某个事件,因此我需要从应用程序的开始处将其激活。

我需要连接到两个不同的VHost,所以我需要创建两个连接。

问题是,当我启动应用程序时,它会不断创建连接,直到服务器崩溃!

在Rabbitmq管理中,我可以看到创建了很多ConnectionChannels

我不知道为什么会这样。

通常,我想知道在dotnet core中启动应用程序时,连接到其他服务的正确方法是什么。

我正在使用此代码执行此操作:

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");
        }

MessageQueue类:

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();
        }

        ...
    }
c# asp.net-core asp.net-web-api rabbitmq
1个回答
0
投票

要启用后台处理,您需要创建一个实现IHostedService接口的类。

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

此接口有两种方法StartAsyncStopAsync。并且您需要使用依赖注入来注册服务,如下所示:

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

© www.soinside.com 2019 - 2024. All rights reserved.