dotnet 控制台应用程序,使用通用主机 HostedService,Windows Task Scheduler 保持在 运行 状态
dotnet console app, using generic host, HostedService, Windows Task Scheduler stays in running state
试图弄清楚为什么我的控制台应用程序不会停止 运行。
在 dotnet 核心应用程序主要方法中使用以下方法:
await new HostBuilder().
...
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyHostedService>();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
使用以下设置从 Windows 任务计划程序发布和计划该任务有效:
到目前为止一切都很好。所有代码都正确执行。但是,任务保持 运行,过程永远不会结束。 (即使在任务计划程序的 UI 上按刷新后也没有)
这是预期的吗?如果没有,我如何让进程终止?
如果预期的话,在刚刚启动、运行和停止的预定控制台应用程序中使用通用主机/托管服务是否仍然有意义?
答案基于Microsoft.Extensions.Hosting 2.2.0
由于您对 Generic Host:
的使用,此行为是预料之中的
它会保持 运行ning 直到关闭或处置,并且您没有适当的关闭机制。我假设您希望 Generic Host 在 IHostedService.StartAsync(CancellationToken) 完成 MyHostedService
运行 后关闭。事实并非如此,因为可能还有其他 IHostedService 实现按顺序注册和执行, and/or long 运行ning BackgroundService returns 控制其 ExecuteAsync(CancellationToken) 未同步完成以允许其他服务并行 运行。
在您的 MyHostedService
任务完成后通过 RunAsync, you should constructor-inject the IApplicationLifetime into your MyHostedService
and call 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 or Console.CancelKeyPress, both events are subscribed to by the ConsoleLifetime 停止应用程序。
您可以在 docs 中阅读有关生命周期管理的更多信息。
Microsoft.Extensions.Hosting 3.0.0 - 目前处于预览阶段 - 标记为 IApplicationLifetime
已过时并建议使用 IHostApplicationLifetime
代替
试图弄清楚为什么我的控制台应用程序不会停止 运行。
在 dotnet 核心应用程序主要方法中使用以下方法:
await new HostBuilder().
...
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyHostedService>();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
使用以下设置从 Windows 任务计划程序发布和计划该任务有效:
到目前为止一切都很好。所有代码都正确执行。但是,任务保持 运行,过程永远不会结束。 (即使在任务计划程序的 UI 上按刷新后也没有)
这是预期的吗?如果没有,我如何让进程终止?
如果预期的话,在刚刚启动、运行和停止的预定控制台应用程序中使用通用主机/托管服务是否仍然有意义?
答案基于Microsoft.Extensions.Hosting 2.2.0
由于您对 Generic Host:
的使用,此行为是预料之中的它会保持 运行ning 直到关闭或处置,并且您没有适当的关闭机制。我假设您希望 Generic Host 在 IHostedService.StartAsync(CancellationToken) 完成 MyHostedService
运行 后关闭。事实并非如此,因为可能还有其他 IHostedService 实现按顺序注册和执行, and/or long 运行ning BackgroundService returns 控制其 ExecuteAsync(CancellationToken) 未同步完成以允许其他服务并行 运行。
在您的 MyHostedService
任务完成后通过 RunAsync, you should constructor-inject the IApplicationLifetime into your MyHostedService
and call 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 or Console.CancelKeyPress, both events are subscribed to by the ConsoleLifetime 停止应用程序。
您可以在 docs 中阅读有关生命周期管理的更多信息。
Microsoft.Extensions.Hosting 3.0.0 - 目前处于预览阶段 - 标记为 IApplicationLifetime
已过时并建议使用 IHostApplicationLifetime
代替