4

I've got the following code that I'm trying to use to trap Ctrl+C in a console app:

    /// <summary>
    /// A driver program for testing 
    /// </summary>
    /// <param name="args">Arguments to the program</param>
    static void Main(string[] args)
    {
        var program = new Program();

        Console.Clear();
        Console.TreatControlCAsInput = false;
        Console.CancelKeyPress += program.OnCancelKeyPress;

        program.Run(args.FirstOrDefault() ?? "3.26.200.125");

        Console.WriteLine("Press any key to continue ...");
        Console.ReadKey();
    }

    /// <summary>
    /// Called when [cancel key press].
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.ConsoleCancelEventArgs"/> instance containing the event data.</param>
    internal void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e)
    {
        this.Continue = false;
        e.Cancel = true;
    }

I've already checked the questions here and here, but for some reason, when I press Control+C, Visual Studio 2010 won't get into my handler in the debugger, I just get a 'source code unavailable' screen, and the opportunity to continue debugging, and that's it. Does anybody have any idea why I'm not getting into the handler ? I'm sure I'm just missing something simple.

Community
  • 1
  • 1
Alex Marshall
  • 10,162
  • 15
  • 72
  • 117
  • This is also when I'm debugging, when I run the program in release it works fine. Is this just a visual studio issue that I'm running into ? – Alex Marshall Feb 27 '12 at 23:23
  • Have you tried setting a breakpoint in the control handler? There may be something causes Visual Studio to break execution before your handler is run. You could then see if continuing got into the control handler later. – Guvante Feb 27 '12 at 23:24
  • Yes, I've placed a breakpoint in the handler, and it never gets hit. As soon as I hit F5 at the point mentioned above to continue (hopefully into my handler), the program just resumes running as though nothing had happened and no interrupt key had been hit. – Alex Marshall Feb 27 '12 at 23:28
  • 1
    By design for VS2010 due to changes in the debugger. Ctrl+C now acts similar to Debug + Break All. A workaround, of sorts, is to enable unmanaged code debugging, click Continue on the message box and your breakpoint will be hit. – Hans Passant Feb 28 '12 at 00:26

3 Answers3

4

Apparently there is a bug a work around from the Connect page is:

In the meantime, to work around this problem, you can enable mixed-mode debugging. Then, when you hit Ctrl-C and a dialog pops up notifying you of the first chance Ctrl-C exception, click "Continue". You should then hit the breakpoint in your handler.

Community
  • 1
  • 1
Guvante
  • 18,775
  • 1
  • 33
  • 64
2

The code below works great for me

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Clear();
            Console.WriteLine("Press X to quit");
            Console.TreatControlCAsInput = false;
            Console.CancelKeyPress += (s, ev) =>
                                          {
                                              Console.WriteLine("Ctrl+C pressed");
                                              ev.Cancel = true;
                                          };

            while (true)
                if (Console.ReadKey().Key == ConsoleKey.X)
                    break;
        }
    }
}

Hope this helps!

Ani
  • 10,826
  • 3
  • 27
  • 46
  • Yes, but the point isn't to demonstrate that. Just trap Ctrl+C. Also: Did you even try it? As a simplistic example it works as intended. – Ani Jan 04 '18 at 22:13
  • Yes, I am working on something very similar and testing it as we speak. However, mine is more complex as I have added the asynchronous stuff to make it non-blocking w/ cancellation, etc. – Latency Jan 05 '18 at 01:33
0

When Main exits, the event handler you've registered with Console.CancelKeyPress += program.OnCancelKeyPress gets garbage collected. Then, when the OS tries to access the delegate, there is no code to be run.

You must declare a static delegate to be run outside the scope of Main and then assign it within Main so that it stays in scope when the OS attempts to call back to it.

Buddy
  • 131
  • 1
  • 4
  • 1
    That's clearly not the case, since the handler runs fine when I'm not debugging in Visual Studio. – Alex Marshall Feb 28 '12 at 16:05
  • You are correct. The answer I offered worked at a time when I was registering a Ctrl-C handler via Windows API calls rather than the method you showed above. It looks like you got it figured out, so that's good news. – Buddy Feb 28 '12 at 17:46