I would like to be able to trap Ctrl+C in a C# console application so that I can carry out some cleanups before exiting. What is the best way of doing this?
I would like to be able to trap Ctrl+C in a C# console application so that I can carry out some cleanups before exiting. What is the best way of doing this?
The Console.CancelKeyPress event is used for this. This is how it's used:
public static void Main(string[] args)
{
Console.CancelKeyPress += delegate {
// call methods to clean up
};
while (true) {}
}
When the user presses Ctrl+C the code in the delegate is run and the program exits. This allows you to perform cleanup by calling necessary methods. Note that no code after the delegate is executed.
There are other situations where this won't cut it. For example, if the program is currently performing important calculations that can't be immediately stopped. In that case, the correct strategy might be to tell the program to exit after the calculation is complete. The following code gives an example of how this can be implemented:
class MainClass
{
private static bool keepRunning = true;
public static void Main(string[] args)
{
Console.CancelKeyPress += delegate(object? sender, ConsoleCancelEventArgs e) {
e.Cancel = true;
MainClass.keepRunning = false;
};
while (MainClass.keepRunning) {
// Do your work in here, in small chunks.
// If you literally just want to wait until Ctrl+C,
// not doing anything, see the answer using set-reset events.
}
Console.WriteLine("exited gracefully");
}
}
The difference between this code and the first example is that e.Cancel is set to true, which means the execution continues after the delegate. If run, the program waits for the user to press Ctrl+C. When that happens the keepRunning variable changes value which causes the while loop to exit. This is a way to make the program exit gracefully.
See MSDN:
Article with code samples:
I can carry out some cleanups before exiting. What is the best way of doing this Thats is the real goal: trap exit, to make your own stuff. And neigther answers above not makeing it right. Because, Ctrl+C is just one of many ways to exiting app.
What in dotnet c# is needed for it - so called cancellation token passed to Host.RunAsync(ct) and then, in exit signals traps, for Windows it would be
private static readonly CancellationTokenSource cts = new CancellationTokenSource();
public static int Main(string[] args)
{
// For gracefull shutdown, trap unload event
AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
{
cts.Cancel();
exitEvent.Wait();
};
Console.CancelKeyPress += (sender, e) =>
{
cts.Cancel();
exitEvent.Wait();
};
host.RunAsync(cts);
Console.WriteLine("Shutting down");
exitEvent.Set();
return 0;
}
...
Detect SIGTERM and ctrl+c:
CancellationTokenSource ctSource = new();
CancellationToken ct = ctSource.Token;
void ExitHandler()
{
// You can add any arbitrary global clean up
Console.WriteLine("Exiting...");
ctSource.Cancel();
}
// Assign exit handler to be called when the process is terminated
// or the user hits CTRL+C
AppDomain.CurrentDomain.ProcessExit += (sender, args) => ExitHandler();
Console.CancelKeyPress += (sender, args) => ExitHandler();
// Then you can use the cancellation token to check for exit:
Console.WriteLine("Ready to gracefully shut down!");
while (!ct.IsCancellationRequested)
{
Console.WriteLine($"Exit not detected, waiting another 10s.");
Task.Delay(10000, ct).Wait(ct);
}