Capturing Ctrl-C in Console Applications
Console applications can be exited by the user by pressing Ctrl-C or Ctrl-Break. During multiple step operations that could leave the system in an inconsistent state, these commands should be intercepted to allow for graceful and safe exiting.
Breaking Out of Console Applications
When you develop a console application, you should remember that your users can terminate it unexpectedly using keystrokes. They can press Ctrl-C or Ctrl-Break to indicate that they wish the program to stop. If you have not added code to cope with these key combinations, your program can exit unexpectedly, potentially leaving the system in an invalid state. For example, if your console application moves files by copying them and then deleting the original, it is possible that the copy could complete but the process may be terminated before the delete. You would then be left with duplicated files, which the user would likely not expect.
To cope with such situations, you can capture when the user attempts to halt your code. For Ctrl-C, you can respond to the keypress by executing additional functionality. If you wish, you can also elect to prevent the termination and return to the point in the code that was reached before the interruption. For Ctrl-Break, you are more limited. You can execute recovery code before the program halts but you cannot cancel the request to exit.
Capturing Break Keypresses
You intercept attempts to break out of your console application by subscribing to the Console class's static CancelKeyPress event. This is raised when the user presses either of the two breaking key combinations. The event is based upon an event handler that provides an instance of the ConsoleCancelEventArgs class. This includes the SpecialKey property, which holds a value from the ConsoleSpecialKey enumeration. The value is either ControlC or ControlBreak, depending upon the keys pressed. The event arguments also include the Cancel property, which may be set to true to cancel the early termination altogether. This only works if the user pressed Ctrl-C. Setting the property in response to Ctrl-Break causes an exception to be thrown.
The code below demonstrates the use of the event. A for loop cause causes a thirty second delay, with each second being displayed in the console. If the code is not halted, this loop will run to completion before the "Done!" message is displayed. During each iteration the loop checks the value of the _cancelled variable. This variable's value will be set to true if the user presses Ctrl-C.
class Program static bool _cancelled;
static void Main(string args)
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
for (int i = 0; i < 30; i++)
if (_cancelled) break;
Console.CancelKeyPress -= new ConsoleCancelEventHandler(Console_CancelKeyPress);
static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
if (e.SpecialKey == ConsoleSpecialKey.ControlC)
_cancelled = true;
e.Cancel = true;
If you run the code to completion, without breaking out by pressing one of the key combinations, the thirty loop iterations are displayed before the "Done!" message. Be sure to use Ctrl-F5 to start the program without debugging.
Press any key to continue . . .
If you press Ctrl-C during the loop's execution, the event is triggered. This causes the display of the message, "Cancelling" and the _cancelled variable is set. This tells the loop to break early. The Cancel property of the event arguments is also set. This prevents the immediate termination of the code, returning control to the loop. The loop sees the change in the _cancelled variable and exits early so that the final message can be displayed and the software can close gracefully.
Press Press any key to continue . . .
When Ctrl-Break is pressed the "Cancelling" message is displayed. In normal circumstances you would use this opportunity to return the system to a consistent state. As the termination cannot be cancelled, when the event handler code completes, the program halts. The console output is shown below. Note that control never returns to the loop and the final "Done!" message is not seen.
^CPress any key to continue . . .
3 July 2012