Skip to content

Graceful cancellation

Adam Bajguz edited this page Aug 18, 2020 · 3 revisions

It is possible to gracefully cancel execution of a command and preform any necessary cleanup. By default an app gets forcefully killed when it receives an interrupt signal (Ctrl+C or Ctrl+Break), but you can override this behavior.

In order to make a command cancellation-aware, you need to call console.GetCancellationToken(). This method returns a CancellationToken that will trigger when the user issues an interrupt signal. Note that any code that comes before the first call to GetCancellationToken() will not be cancellation-aware and as such will terminate instantly. Any subsequent calls to this method will return the same token.

[Command("cancel")]
public class CancellableCommand : ICommand
{
    public async ValueTask ExecuteAsync(IConsole console)
    {
        console.Output.WriteLine("Printed");

        // Long-running cancellable operation that throws when canceled
        await Task.Delay(Timeout.InfiniteTimeSpan, console.GetCancellationToken());

        console.Output.WriteLine("Never printed");
    }
}

Keep in mind that a command may delay cancellation only once. If the user decides to press Ctrl+C again after the first time, the execution will be forcefully terminated.

Clone this wiki locally