.net-core - Environment.Exit 后托管服务未终止

标签 .net-core

我有一个带有托管服务的 .NET core 3.1 应用程序,它在 Windows 上作为控制台应用程序运行。

如果出现错误,我会尝试使用 Environment.Exit(1) 终止工作人员.

现在的问题是,如果 Enviroment.Exit()在任何 await 之前调用在 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);
    }
  }

我希望两者的行为方式相同,但显然情况并非如此。
对此的任何解释将不胜感激!

更新 :应用程序应该能够作为控制台应用程序和 Windows 服务运行。如果它崩溃,则需要非零返回码才能重新启动它。
显然 Windows 不会重新启动以代码 0 退出的服务。

最佳答案

我相信您看到的行为是 .NET Core 运行时启动方式的副作用:它调用 ExecuteAsync对于每个后台工作人员,然后等待它完成。所以一个同步的ExecuteAsync可能会导致问题。我用过Task.Run解决这个问题。

In case of an error I'm trying to terminate the worker with Environment.Exit(1).



我建议不要使用 Environment.Exit一点也不。相反,通过注入(inject) IHostApplicationLifetime 来控制关闭。并调用 StopApplication .这将触发 stoppingToken对于您的每个后台服务,如果它们忽略它,它们将在超时后被强制终止。

关于.net-core - Environment.Exit 后托管服务未终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59879271/

相关文章:

.net-core - .NET Core 2 Web 应用程序和 Electron js 桌面应用程序 - 通用身份验证系统

Azure AD B2C + 应用服务 + 功能 : How to flow the auth?

.net-core - 在 .net Framework 而不是 .netcore 中创建 Microsoft Bot 项目?

entity-framework - EntityFramework 正在缓存旧的过时数据,我不知道如何阻止它

c# - 在 Visual Studio 2017 中设置默认的 C# 构建语言版本

c# - Nunit 测试命名约定示例

.net - 与容器上RabbitMQ的连接问题

c# - 未发现 NUnit v3 单元测试 - "Discover test finished: 0 found"

.net-core - Blazor .Net 服务器端加载 LocalStorage 数据的位置

c# - Request Header中的JWT在接收.Net Core API中是不一样的