简体   繁体   中英

dotnet console app, using generic host, HostedService, Windows Task Scheduler stays in running state

Trying to figure out why my console app won't stop running.

Using the following approach in a dotnet core application main method:

await new HostBuilder().
...
 .ConfigureServices((hostContext, services) =>
  {     
     services.AddHostedService<MyHostedService>(); 
  })
 .UseConsoleLifetime()
 .Build()
 .RunAsync();

Publishing and scheduling that task from the Windows Task Scheduler using the following settings works:

Windows Task Scheduler设置

All good so far. All code is properly executed. However, the task stays running, the process never ends. (not even after pressing refresh on the UI of the task scheduler)

Is this expected? If not, how do I get the process to terminate?

If expected, does it still make sense then, to use Generic Host / Hosted Service in a scheduled console app that just starts, runs, and stops?

Answer based on Microsoft.Extensions.Hosting 2.2.0

This behavior is expected, due to your usage of the Generic Host :

It keeps running until shut down or disposed, and you have no shutdown mechanism in place. I assume you expect the Generic Host to shut down after IHostedService.StartAsync(CancellationToken) of your MyHostedService ran to completion. This is not the case, because there might be other IHostedService implementations registered and executed in sequence, and/or a long running BackgroundService which returns control when its ExecuteAsync(CancellationToken) is not completing synchronously to allow other services to run in parallel.

To stop your application gracefully after your MyHostedService completes when running the host via RunAsync , you should constructor-inject the IApplicationLifetime into your MyHostedService and call StopApplication after your Task has completed.

internal class MyHostedService : IHostedService
{
    private readonly IApplicationLifetime _appLifetime;

    public MyHostedService(IApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        await Task.Delay(1000); //your scheduled work

        _appLifetime.StopApplication();
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Also, the application may be stopped via either AppDomain.CurrentDomain.ProcessExit or Console.CancelKeyPress , both events are subscribed to by the ConsoleLifetime , which is pre-registered as the default lifetime implementation.

You can read more about lifetime management in the docs .

Microsoft.Extensions.Hosting 3.0.0 - currently in preview - marked IApplicationLifetime obsolete and recommends using IHostApplicationLifetime instead

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM