Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

c# - 同时运行长时间任务IHosted服务,并且可以手动打开和关闭(Running a long task IHosted service at the same time and can manually turned on and off)

hi i am having a problem in running a long task for my background service using the IHostedService at first it really work fine but in the long run the background service suddenly stopped with this thread exited code:

(嗨,我在使用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).

i register my background service as

(我将后台服务注册为)

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

because in the future i want to manually turned on and off my background services with use of

(因为将来我想使用手动打开和关闭后台服务)

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

and this was my code in my background services StartAsync

(这是我在后台服务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;
    }

I am confuse if there are some problems with registering my background service because i see my background service starts but in the long run it suddenly stopped i already get rid of those Thread.Sleep() in my background services hope you can help thanks in advance.

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

  ask by James Tubiano translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of managing hosted services lifetime in a such weird way, you can set configuration for services inside appsettings.json , configure it as reloadOnChange: true , and use IOptionsMonitor<> to access current values from appsettings.json .

(不必以这种怪异的方式来管理托管服务的生命周期,您可以在appsettings.json设置服务的配置,将其配置为reloadOnChange: true ,然后使用IOptionsMonitor<>来访问appsettings.json当前值。)

And use that settings as a cancellation for started task inside hosted service's StartAsync method.

(并使用该设置取消托管服务的StartAsync方法中的已启动任务。)

And you need to listen to OnChange event of IOptionsMonitor<> for restarting services.

(并且您需要侦听IOptionsMonitor<> OnChange事件以重新启动服务。)

appsettings.json :

(appsettings.json :)

 "HostedService": {
    "RunService1": true
  }

Register that options so:

(注册该选项,以便:)

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

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

And then create HostedService1 and register with the help of the AddHostedService :

(然后创建HostedService1并在AddHostedService的帮助下进行AddHostedService :)

 services.AddHostedService<HostedService1>();

And here is the example for StartAsync :

(这是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;
        }

        ...
   }

In case of any changes inside appSettings.json , you _options.CurrentValue.RunService1 will be reloaded automatically.

(如果appSettings.json内部发生任何更改,则_options.CurrentValue.RunService1将自动重新加载。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...