10

I am writing a Console app in C# 4 and want to gracefully cancel my program and Ctrl + C is pressed. The following code I have used many times before, but now when trying to use it in .NET 4, it seems a strange unhandled exception is occurring.

namespace ConsoleTest
{
    class Program
    {
        private static bool stop = false;

        static void Main(string[] args)
        {
            System.Console.TreatControlCAsInput = false;
            System.Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            while (!stop)
            {
                System.Console.WriteLine("waiting...");
                System.Threading.Thread.Sleep(1000);
            }
            System.Console.WriteLine("Press any key to exit...");
            System.Console.ReadKey(true);
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            stop = true;
            e.Cancel = true;
        }
    }
}

If I change the Target Framework to .NET 3.5, it works.

EDIT: It seems this person is seeing the same issue: http://johnwheatley.wordpress.com/2010/04/14/net-4-control-c-event-handler-broken/

BigJoe714
  • 6,732
  • 7
  • 46
  • 50
  • What is the exception? Where does it happen? You can enable breaking on various exceptions in the Exceptions dialog in VS (Debug -> Exceptions or Ctrl+Alt+E). – Chris Schmich May 19 '10 at 14:03
  • Its not a normal exception. The person in the link I added describes it as a "program fault". Here is a screenshot of what I see when pressing Ctrl+C when target framework is .NET 4 running in VS 2010: http://img227.imageshack.us/img227/5871/consoletest.jpg – BigJoe714 May 19 '10 at 14:07
  • Just a guess, but you might be able to workaround this issue by disabling the hosting process: right-click on your project, select Properties, go to the Debug tab, and uncheck "Enable the Visual Studio hosting process". – Chris Schmich May 19 '10 at 14:10

2 Answers2

13

This is a known issue on Microsoft Connect.

Note that it does work outside of the debugger.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
2

For a console application under VS2010 and .NET 4.0, i am using the following (not very clean) workaround:

  1. in Project properties, under [Debug], check [Enable unmanaged code debugging];
  2. during the startup code of your Program class, insert the following (this is .NET 2 style, use lambdas at your discretion):

Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
  if (e.SpecialKey == ConsoleSpecialKey.ControlC)
  {
    e.Cancel = true; // tell the CLR to keep running
  }
  else if (e.SpecialKey == ConsoleSpecialKey.ControlBreak)
  {
    //e.Cancel = true; // "Applications are not allowed to cancel the ....
  }
  // do whatever you must to inform threads on application exit, etc
}

Although not obvious, this code will allow you to debug your CTRL-C handler like so:

  1. start your program under the debugger (F5);
  2. make sure your program's console has the focus;
  3. press ctrl+pause (on my latitude e6500, i need to hold ctrl and Fn and F12);

The debugger will ask you about this interruption, click [Ignore] and you will find yourself in the handler (make sure a breakpoint was set)

THE SAME code will execute if ctrl+c is pressed, the only difference is you must set e.Cancel to true.

As pointed out by everybody else, the problem DOES NOT exist at runtime, this workaround is ONLY for stepping through the handler.

LarsTech
  • 80,625
  • 14
  • 153
  • 225