试图弄清楚为什么我的控制台应用程序不会停止运行。
在dotnet核心应用程序主方法中使用以下方法:
await new HostBuilder().
...
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyHostedService>();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
使用以下设置从Windows任务计划程序发布和计划该任务有效:
到目前为止都很好。所有代码都已正确执行。但是,任务保持运行,该过程永远不会结束。 (即使在任务调度程序的UI上按下刷新后也没有)
这是预期的吗?如果没有,我如何让程序终止?
如果预期,那么在一个刚启动,运行和停止的计划控制台应用程序中使用通用主机/托管服务是否仍然有意义?
答案基于Microsoft.Extensions.Hosting 2.2.0
由于您使用Generic Host,此行为是预期的:
它一直运行直到关闭或处理,并且您没有关闭机制。我认为你期望Generic Host在你的IHostedService.StartAsync(CancellationToken)的MyHostedService
完成后关闭。情况并非如此,因为可能有其他IHostedService实现按顺序注册和执行,和/或长时间运行的BackgroundService,当ExecuteAsync(CancellationToken)没有同步完成以允许其他服务并行运行时返回控制。
在MyHostedService
通过RunAsync运行主机后完成后,优雅地停止你的应用程序,你应该constructor-inject 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;
}
}
此外,应用程序可以通过AppDomain.CurrentDomain.ProcessExit或Console.CancelKeyPress停止,两个事件都由ConsoleLifetime订阅,docs预先注册为默认的生命周期实现。
您可以在IApplicationLifetime
中阅读有关终身管理的更多信息。
Microsoft.Extensions.Hosting 3.0.0 - 目前处于预览状态 - 标记为IHostApplicationLifetime
已过时,建议使用qazxswpoi代替