首页 > 解决方案 > 在 ASP.NET Core Web API 应用程序中禁用 Ctrl+C 关闭

问题描述

我正在尝试为在 ASP.NET Core Web 应用程序中创建的 API 主机禁用自动启用的“Ctrl+C”关闭。以前在这里问过同样的问题,但是使用下面的代码对我不起作用——启动时仍然显示“按 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>

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

解决方案


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.

参考


推荐阅读