【问题标题】:Disable Ctrl+C Shutdown in ASP.NET Core Web API Application在 ASP.NET Core Web API 应用程序中禁用 Ctrl+C 关闭
【发布时间】:2021-10-02 15:22:04
【问题描述】:

我正在尝试为在 ASP.NET Core Web 应用程序中创建的 API 主机禁用自动启用的“Ctrl+C”关闭。之前here 提出了同样的问题,但使用下面的代码对我不起作用——启动时仍然显示“按 Ctrl+C”消息,实际上,按 Ctrl+C 会停止应用程序。

如何关闭此行为?

添加 Console.CancelKeyPress 处理程序以捕获 Ctrl-C 不起作用 - 设置 'Cancel = True' 不会阻止 ASP.NET 主机看到 Ctrl-C 并停止。

代码如下:

public static void Main(string[] args) {
    var tokenSource = new CancellationTokenSource();
    var task = CreateHostBuilder(args).Build().RunAsync(tokenSource.Token);
    while (!task.IsCompleted) {
        // TODO: Other stuff...
        Thread.Sleep(1000);
    };
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder => {
            webBuilder.UseStartup<Startup>();
        });

这是应用程序启动时的输出(请注意“Press Ctrl+C...”消息仍然存在):

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: <path>

【问题讨论】:

  • 所谓问题中的解决方案围绕Console.CancelKeyPress。但是在 ASP.NET Core 之前拦截退出事件是不够的。
  • 解决方案是实现一个自定义的IHostLifetime,替换默认的ConsoleLifetime。我会在实现中添加一个答案,但我必须等到问题重新打开,如果有的话。
  • 注册为单例即可:services.AddSingleton&lt;IHostLifetime, NoopConsoleLifetime&gt;()

标签: c# asp.net-core asp.net-core-webapi


【解决方案1】:

ASP.NET Core 有一个主机生命周期的概念来管理应用程序的生命周期。

有几种实现方式,例如

  • ConsoleLifetime,监听Ctrl+CSIGTERM 并启动关机。
  • SystemdLifetime,通知 systemd 服务开始和停止
  • WindowsServiceLifetime,与 Windows 服务集成

我们将插入我们自己的实现,它将监听Ctrl+C 键,并取消它以防止它停止应用程序:

public class NoopConsoleLifetime : IHostLifetime, IDisposable
{
    private readonly ILogger<NoopConsoleLifetime> _logger;

    public NoopConsoleLifetime(ILogger<NoopConsoleLifetime> logger)
    {
        _logger = logger;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    public Task WaitForStartAsync(CancellationToken cancellationToken)
    {
        Console.CancelKeyPress += OnCancelKeyPressed;
        return Task.CompletedTask;
    }

    private void OnCancelKeyPressed(object? sender, ConsoleCancelEventArgs e)
    {
        _logger.LogInformation("Ctrl+C has been pressed, ignoring.");
        e.Cancel = true;
    }

    public void Dispose()
    {
        Console.CancelKeyPress -= OnCancelKeyPressed;
    }
}

然后向 DI 注册:

services.AddSingleton<IHostLifetime, NoopConsoleLifetime>();

当您启动应用程序时,您将无法使用 Ctrl+C 停止它:

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Demo.NoopConsoleLifetime[0]
      Ctrl+C has been pressed, ignoring.
info: Demo.NoopConsoleLifetime[0]
      Ctrl+C has been pressed, ignoring.

参考

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 2016-01-09
    相关资源
    最近更新 更多