Home Capturing CancelKeyPress to stop an async console app at a safe point
Reply: 0

Capturing CancelKeyPress to stop an async console app at a safe point

awj
1#
awj Published in 2018-01-12 09:06:06Z

I'm working on a small utility console app, built in C# 7.1 (which has async Main support).

The app takes one of several input commands and then starts a long-running process which iterates through tens of thousands of items, processing each.

I want to be able to cancel this process at any time (using CTRL+C), although the program should not immediately cancel but instead should finish the current iteration, then stop.

Here's a shortened version of what I have so far.

private static bool _cancel;    

private static async Task Main(string[] args)
{
    Console.CancelKeyPress += (sender, eventArgs) =>
                                      {
                                          eventArgs.Cancel = true;                                              _logger("Migration will be stopped after the current record has been completed.\n");
                                          _cancel = true;
                                      };

    while (!_cancel)
    {
        var input = Console.ReadLine();

        // handle the various input commands
    }
}

Inside the methods which run the (optional) long-running process there is logic which checks for this global _cancel variable:

private static async Task RunPersonMigration(Order order)
{
    var nextPerson = // ...
    while (nextPerson.IsValid)
    {
        // business logic

        if (_cancel)
        {
            _logger("Person migration stopped by user.\n");
            return;
        }

        nextPerson = // ...
    }
}

However, whenever I hit CTRL+C the Visual Studio debugger asks me to locate an assembly, and it's usually a different assembly each time. For example, I've been asked to locate waithandle.cs and thread.cs. Because I'm unable to locate such files, the running debug process abruptly stops.

I can never see which line is causing the problem, and no amount of breakpoints helps.

Basically, I'm trying to use CTRL+C to exit a long-running process without exiting the console app.

Can anyone tell me how I should correctly handle cancelling a long-running console process at a point of my choosing?

UPDATE:
If I update my CancelKeyPress delegate...

Console.CancelKeyPress += (sender, eventArgs) =>
                                  {
                                      **eventArgs.Cancel = true;**                                              _logger("Migration will be stopped after the current record has been completed.\n");
                                      _cancel = true;
                                  };

then this stops the program from crashing to a close, but I'd still like to be able to trap CTRL+C and use it as a means of exiting the long-running process without exiting the console app itself. Is this even possible?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.311342 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO