[英]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: 在dotnet核心应用程序主要方法中使用以下方法:
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任务计划程序发布和计划任务:
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 基于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. 我假定你所期望的通用主机关机后IHostedService.StartAsync(的CancellationToken)您的
MyHostedService
运行完成。 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. 并非如此,因为可能还会依次注册和执行其他IHostedService实现,并且/或者长时间运行的BackgroundService在其ExecuteAsync(CancellationToken)未同步完成以允许其他服务并行运行时返回控制。
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. 要停止你的应用程序你摆好后
MyHostedService
运行通过主机时完成RunAsync ,你应该构造函数注入的IApplicationLifetime到您的MyHostedService
并调用StopApplication你的任务已经完成了。
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. 另外,可以通过AppDomain.CurrentDomain.ProcessExit或Console.CancelKeyPress停止应用程序,这两个事件都由ConsoleLifetime订阅,该控制台已预先注册为默认生存期实现。
You can read more about lifetime management in the docs . 您可以在docs中阅读有关生命周期管理的更多信息。
Microsoft.Extensions.Hosting 3.0.0 - currently in preview - marked IApplicationLifetime
obsolete and recommends using IHostApplicationLifetime
instead Microsoft.Extensions.Hosting
IApplicationLifetime
当前处于预览状态-标记为IApplicationLifetime
已过时,建议改为使用IHostApplicationLifetime
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.