如何在.NET 4中使用Console.CancelKeyPress? (在.NET 3.5及更低版本中正常工作)

我正在C#4中编写一个控制台应用程序,并希望优雅地取消我的程序并按下Ctrl + C. 我之前使用过很多次代码,但现在尝试在.NET 4中使用它时,似乎发生了一个奇怪的未处理exception。

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; } } } 

如果我将目标框架更改为.NET 3.5,它可以工作。

编辑:看来这个人看到了同样的问题: http : //johnwheatley.wordpress.com/2010/04/14/net-4-control-c-event-handler-broken/

这是Microsoft Connect上的已知问题。

请注意,它在调试器之外工作。

对于VS2010和.NET 4.0下的控制台应用程序,我使用以下(不是很干净)的解决方法:

  1. 在Project属性中的[Debug]下,选中[Enable unmanaged code debugging];
  2. 在您的Program类的启动代码中,插入以下内容(这是.NET 2样式,您可以自行决定使用lambdas):

 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 } 

虽然不是很明显,但是这段代码将允许您调试CTRL-C处理程序,如下所示:

  1. 在调试器下启动你的程序(F5);
  2. 确保你的程序控制台有焦点;
  3. 按ctrl + pause(在我的纬度e6500上,我需要按住ctrl和Fn和F12);

调试器将询问您有关此中断的信息,单击[忽略],您将发现自己处于处理程序中(确保设置了断点)

如果按下ctrl + c,将执行相同的代码,唯一的区别是您必须将e.Cancel设置为true。

正如其他人所指出的那样,问题在运行时不存在,这种解决方法仅适用于单步执行处理程序。