Below is my simple code that runs an IHostedService
internal class Program {
public static Task Main(string[] args) {
var host = new HostBuilder().ConfigureServices((hostcontext, services) => {
services.AddHostedService<MyService>();
}).Build();
host.Run();
return Task.CompletedTask;
}
}
public class MyService : IHostedService {
public Task StartAsync(CancellationToken cancellationToken) {
return Task.Run(() => {
while (true) {
Console.WriteLine("Starting Service");
}
});
}
public Task StopAsync(CancellationToken cancellationToken) {
Console.WriteLine("Stopping service");
return Task.CompletedTask;
}
}
So when I want to stop the service by pressing ctrl + C in the console, I exepct to see the service stops and console prints "Stopping service".
But when I press Ctrl + C, the service continues running in the infinite loop, which I don't understand.
I think Task.Run() queues a work item on the thread pool, then a background thread from thread pool to pick up the job, so in my example, it is a worker thread (worker thread's id is 4, main thread's id is 1) that executes the while loop. So when I press ctrl + S, the service should stop, then why the running background thread stops the service being stopped, isn't that when a application terminals, all background jobs/ threads terminates too? I mean if Task.Run() runs creates a foreground threads then I can understand, because all foreground threads need to finish before the applciation could be stopped.
P.S:
I can pass the CancellationTokento stop the while loop, I understand I can do that and in the while loop, I check if the token is cancalled etc...
but I don't understand why I have to do that, because the running thread is a background thread, not a foreground thread, so why all background threads need to finish first the the StopAsync() can be invoked? i.e how does a running background thread stops the exection flow reach to StopAsync()?
If you want to stop a Task try using a cancellation token in MyServiceClass
Here is my example:
public class MyService : IHostedService
{
private CancellationTokenSource _ts;
public Task StartAsync(CancellationToken cancellationToken)
{
_ts = new CancellationTokenSource();
return Task.Factory.StartNew(() =>
{
while (true)
{
Console.WriteLine("Starting Service");
Thread.Sleep(500);
if (_ts.Token.IsCancellationRequested)
{
Console.WriteLine("Stopping service");
break;
}
}
}, _ts.Token);
}
public Task StopAsync(CancellationToken cancellationToken)
{
_ts.Cancel();
return Task.CompletedTask;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With