如何实现Ctrl+C终止时输出指定内容的C#控制台应用
C#控制台应用优雅处理Ctrl+C终止方案
要实现按下Ctrl+C时保留最后一次时间输出,再打印总结语句,核心是避免事件线程打断主线程的输出流程,同时让主线程可控退出。以下是线程安全的实现方案:
关键思路
- 注册
Console.CancelKeyPress事件,阻止系统直接终止进程,转而通过标记变量通知主线程退出循环。 - 使用
volatile变量确保跨线程的状态可见性,避免主线程读取到过期的取消标记。 - 一次性构建完整输出字符串再打印,减少分步输出被打断的可能。
- 在
finally块中执行总结输出,保证无论循环如何结束都能执行。
完整代码
using System; class Program { // volatile保证变量跨线程的可见性 private static volatile bool _cancelRequested = false; static void Main(string[] args) { // 注册Ctrl+C事件处理器 Console.CancelKeyPress += OnCancelKeyPress; try { while (!_cancelRequested) { var now = DateTime.Now; // 一次性构建完整输出内容,避免分步Write被打断 string timeOutput = $"{now} {now.Millisecond}"; Console.Write(timeOutput); Console.CursorLeft = 0; // 回到行首覆盖输出 // 可选:添加小延迟降低CPU占用,同时让输出更稳定 System.Threading.Thread.Sleep(10); } } finally { // 移到新行,避免覆盖最后一次时间输出 Console.WriteLine(); Console.WriteLine("Goodbye!"); } } private static void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e) { // 阻止系统立即终止进程,让主线程完成清理 e.Cancel = true; // 设置取消标记,通知主线程退出循环 _cancelRequested = true; } }
方案说明
- 事件处理逻辑:
OnCancelKeyPress中设置e.Cancel = true是避免进程被强制终止的核心,这样主线程能继续执行直到循环结束。 - volatile变量:确保主线程每次检查
_cancelRequested时都读取最新值,不会因为CPU缓存导致延迟响应取消请求。 - 一次性输出:将时间和毫秒数整合成一个字符串再打印,避免分步
Console.Write时被事件线程打断,造成输出混乱。 - finally块:保证总结语句一定会被执行,即使循环中出现异常也不例外。
内容的提问来源于stack exchange,提问作者Dan Stevens
相关产品推荐
相关产品推荐

