我有一个带有托管服务的 .NET Core 3.1 应用程序,该应用程序在 Windows 上作为控制台应用程序运行。
如果出现错误,我会尝试使用Environment.Exit(1).
现在的问题是,如果Enviroment.Exit()在任何awaitin之前调用ExecuteAsync,应用程序不会终止。它记录Waiting for the host to be disposed. Ensure all 'IHost' instances are wrapped in 'using' blocks.然后无限期地挂起。
当我在调用Enviroment.Exit()它之前等待任何东西时也会记录它,但它会按预期终止。
这是我可以想出的最简单的代码来重现问题。
该NotTerminatingWorker挂起永远的TerminatingWorker终止。唯一的区别是一个微小的Task.Delay:
public class Program {
public static async Task Main(string[] args) {
using var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) {
return Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => { services.AddHostedService<NotTerminatingWorker>(); });
}
}
public class NotTerminatingWorker : BackgroundService {
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
Environment.Exit(1);
}
}
public class TerminatingWorker : BackgroundService {
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
await Task.Delay(1);
Environment.Exit(1);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望两者的行为方式相同,但显然情况并非如此。
对此的任何解释将不胜感激!
更新:该应用程序应该能够作为控制台应用程序和 Windows 服务运行。如果它崩溃,则需要非零返回码才能重新启动它。显然 Windows 不会重新启动以代码 0 退出的服务。
Ste*_*ary 14
我相信您看到的行为是 .NET Core 运行时如何启动的副作用:它调用ExecuteAsync每个后台工作程序,然后等待它完成。所以同步ExecuteAsync会导致问题。我曾经Task.Run解决过这个问题。
如果出现错误,我会尝试使用 Environment.Exit(1) 终止工作程序。
我建议根本不要使用Environment.Exit。相反,通过注入IHostApplicationLifetime和调用StopApplication. 这将触发stoppingToken你的每个后台服务,如果他们忽略它,它们将在超时后被强行终止。
| 归档时间: |
|
| 查看次数: |
2661 次 |
| 最近记录: |