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:
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
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.
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
. And use that settings as a cancellation for started task inside hosted service's StartAsync
method. And you need to listen to OnChange
event of IOptionsMonitor<>
for restarting services.
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
:
services.AddHostedService<HostedService1>();
And here is the example for 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.