Search code examples
c#cancellation-tokencancellationtokensource

How to exit gracefully from a while loop when CancellationTokenSource.Cancel() is used


I have the following program written in dotnet 6:

var cancellationTokenSource = new CancellationTokenSource();

Console.CancelKeyPress += (object? sender, ConsoleCancelEventArgs e) =>
{
    cancellationTokenSource.Cancel();
};

await DoAsync(cancellationTokenSource.Token);

Console.WriteLine("Finished!");

async Task DoAsync(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        Console.WriteLine("Test!");
        await Task.Delay(1000);
    }
}

When I press "Ctrl + C" the program exits with the following error code: "Program.exe exited with code -1073741510". "Finished!" is never written to the screen.

I cannot understand what exactly happens but it seems that cancellationTokenSource.Cancel() throws an exception and the program finishes with error. As far as I understand, when cancellationTokenSource.Cancel() is called cancellationTokenSource.Token.IsCancellationRequested is set to true and no exception should be thrown.

What is the reason the applicatiion to finish with exception and how can I gracefully exit the application when the user presses "Ctrl + C"?

I googled a lot but couldn't find the answer.


Solution

  • Ctrl+C kills the application. As the CancelKeyPress documentation explains, handling the event won't prevent termination.

    To avoid termination you need to set ConsoleCancelEventArgs.Cancel to true

    Console.CancelKeyPress += (object? sender, ConsoleCancelEventArgs e) =>
    {
        e.Cancel=true;
        cancellationTokenSource.Cancel();
    };