4

I am trying to disable the automatically enabled "Ctrl+C" shutdown for an API Host created in an ASP.NET Core Web Application. The same question was asked previously here, but it doesn't work for me using the code below -- the "Press Ctrl+C" message is still shown on startup and, indeed, pressing Ctrl+C stops the application.

How can I turn off this behavior?

Adding Console.CancelKeyPress handler to trap the Ctrl-C doesn't work -- setting 'Cancel = True' doesn't stop the ASP.NET host from seeing the Ctrl-C and halting.

Here's the code:

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>();
        });

And here's the output on application start (note that the "Press Ctrl+C..." message is still there):

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>
3
  • Solutions in the alleged question revolves around Console.CancelKeyPress. But it isn't enough to intercept the exit event before ASP.NET Core does. Commented Jul 26, 2021 at 17:48
  • The solution is to implement a custom IHostLifetime and replace the default ConsoleLifetime. I would have added an answer with the implementation, but I'll have to wait until the question is reopened, if at all. Commented Jul 26, 2021 at 18:10
  • Just register it as singleton: services.AddSingleton<IHostLifetime, NoopConsoleLifetime>() Commented Jul 26, 2021 at 19:09

1 Answer 1

6

ASP.NET Core has a concept of host lifetime to manage the lifetime of an application.

There are a couple of implementations, such as

  • ConsoleLifetime, which listens for Ctrl+C or SIGTERM and initiates shutdown.
  • SystemdLifetime, which notifies systemd of service start & stops
  • WindowsServiceLifetime, which integrates with Windows services

We'll plug in our own implementation, which will listen to Ctrl+C key, and cancel it to prevent it from stopping the application:

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;
    }
}

then register this with DI:

services.AddSingleton<IHostLifetime, NoopConsoleLifetime>();

When you start the application, you will not be able to stop it with 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.

References

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.