How do I use Console.CancelKeyPress in .NET 4? (Works fine in .NET 3.5 and below)

孤街浪徒 提交于 2019-12-22 03:49: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/


回答1:


This is a known issue on Microsoft Connect.

Note that it does work outside of the debugger.




回答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.



来源:https://stackoverflow.com/questions/2866171/how-do-i-use-console-cancelkeypress-in-net-4-works-fine-in-net-3-5-and-below

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!