问题
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:
- in Project properties, under [Debug], check [Enable unmanaged code debugging];
- 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:
- start your program under the debugger (F5);
- make sure your program's console has the focus;
- 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