0

嗨,我在使用 IHostedService 为我的后台服务运行长任务时遇到问题,起初它确实工作正常,但从长远来看,后台服务突然停止,此线程退出代码:

The thread 10824 has exited with code 0 (0x0).
The thread 12340 has exited with code 0 (0x0).
The thread 9324 has exited with code 0 (0x0).
The thread 11168 has exited with code 0 (0x0).
The thread 11616 has exited with code 0 (0x0).
The thread 9792 has exited with code 0 (0x0).

我将我的后台服务注册为

//Register Background 
serviceCollection.AddSingleton<CoinPairBackgroundService>
serviceCollection.AddSingleton<SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<LeaderboardHoursBackgroundService>();

serviceCollection.AddSingleton<IHostedService, CoinPairBackgroundService>();
serviceCollection.AddSingleton<IHostedService, SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardHoursBackgroundService>();

因为将来我想手动打开和关闭我的后台服务

IServiceProvider provider = _serviceProvider.GetService<MyBackgroundServiceHere>();
provider.StartAsync();
provider.StopAsync

这是我在后台服务 StartAsync 中的代码

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogDebug("Leaderboard minute ranking updates is starting");
        Task.Run(async () =>
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                _logger.LogDebug("Leaderboard minute ranking updates  is dequeueing");
                await DequeueRandomCustomers();

                _logger.LogDebug("Leaderboard minute ranking updates  is enqueueing");
                await EnqueueRandomCustomers();

                _logger.LogDebug("Leaderboard minute ranking updates  thread is now sleeping");
                //sleep for 1 minute
                await Task.Delay(new TimeSpan(0, 0, 10));
            }
        });
        return Task.CompletedTask;
    }

如果注册后台服务有问题,我会感到困惑,因为我看到我的后台服务启动了,但从长远来看,它突然停止了,我已经摆脱了后台服务中的那些 Thread.Sleep() 希望你能帮助提前谢谢.

4

1 回答 1

0

无需以这种奇怪的方式管理托管服务的生命周期,appsettings.jsonreloadOnChange: true可以IOptionsMonitor<>appsettings.json. 并使用该设置作为托管服务StartAsync方法中已启动任务的取消。并且您需要侦听重新启动服务的OnChange事件IOptionsMonitor<>

appsettings.json

 "HostedService": {
    "RunService1": true
  }

注册该选项,以便:

public class HostedServiceConfig
{
     public bool RunService1 { get; set; }
}

services.Configure<HostedServiceConfig>(Configuration.GetSection("HostedService"));

然后在以下帮助下创建HostedService1和注册AddHostedService

 services.AddHostedService<HostedService1>();

这是示例StartAsync

  public class HostedService1 : IHostedService
  {
        private readonly IOptionsMonitor<HostedServiceConfig> _options;
        private CancellationToken _cancellationToken;

        public HostedService1(IOptionsMonitor<HostedServiceConfig> options)
        {
            _options = options;

             // Or listen to changes and re-run all services from one place inside `Configure` method of `Startup`
            _options.OnChange(async o =>
            {
                if (o.RunService1)
                {
                    await StartAsync(_cancellationToken);
                }
            });
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            if(_cancellationToken == null) 
            {
                 _cancellationToken = cancellationToken;
            }

            Task.Run(async () =>
            {
                while (!_cancellationToken .IsCancellationRequested || !_options.CurrentValue.RunService1)
                {
                     ....
                }
            });

            return Task.CompletedTask;
        }

        ...
   }

如果内部有任何更改appSettings.json,您_options.CurrentValue.RunService1将自动重新加载。

于 2019-11-30T21:17:26.553 回答