如何避免Console.ReadLine期间按Ctrl-C后执行后续Console.Write语句
核心原因
当在Console.ReadLine()执行期间按下Ctrl+C时,.NET运行时的默认终止逻辑是异步执行的,进程会在极短时间内退出,但退出前仍可能执行完Console.ReadLine()之后的少量代码,因此password: 提示会被输出后进程才完全终止。你之前单独用空值判断不生效的核心原因是没有在判断后强制立即终止进程,单独用CancelKeyPress不生效是因为没有将事件参数的Cancel属性设为true来接管退出逻辑。
可行解决方案
方案1:接管Ctrl+C事件+空值校验+主动立即退出
这个方案不需要修改原有输入逻辑,兼容性最好:
bool isForceExit = false; // 注册Ctrl+C事件处理 Console.CancelKeyPress += (_, e) => { e.Cancel = true; // 禁止运行时默认的异步终止行为 isForceExit = true; }; Console.Write("login: "); string userId = Console.ReadLine(); // 只要触发退出标识或者ReadLine返回空(Ctrl+C场景下ReadLine会返回null),立即强制退出 if (isForceExit || userId == null) { Environment.Exit(0); // 同步立即终止进程,不会执行后续代码 } Console.Write("password: "); // 后续密码读取逻辑
方案2:使用ReadKey逐字符读取输入(临时方案优化版)
如果要更灵活控制输入行为,包括密码回显隐藏,可以直接用ReadKey实现输入逻辑,天然可以拦截Ctrl+C触发:
Console.Write("login: "); StringBuilder userIdBuilder = new(); while(true) { var key = Console.ReadKey(true); if (key.Key == ConsoleKey.C && key.Modifiers == ConsoleModifiers.Control) { Environment.Exit(0); } if (key.Key == ConsoleKey.Enter) { break; } if (key.Key == ConsoleKey.Backspace && userIdBuilder.Length > 0) { userIdBuilder.Remove(userIdBuilder.Length - 1, 1); Console.Write("\b \b"); continue; } if (!char.IsControl(key.KeyChar)) { userIdBuilder.Append(key.KeyChar); Console.Write(key.KeyChar); } } string userId = userIdBuilder.ToString(); Console.WriteLine(); Console.Write("password: "); // 密码输入逻辑和上面类似,只是不需要回显输入的字符
内容的提问来源于stack exchange,提问作者guest
相关产品推荐
相关产品推荐

