C#控制台应用:如何实现循环的暂停与恢复(P/Enter键控制)
问题分析与解决方案
你的代码存在几个关键问题,导致暂停/恢复功能无法正常工作:
- 每次循环都重复注册
Timer_Elapsed事件,会造成事件多次触发,时间打印逻辑混乱。 - 使用阻塞式的
Console.ReadKey(true),会强制程序等待按键输入,无法正常执行循环内的业务逻辑。 - 暂停与恢复的逻辑结构错误,按下P后立刻要求按Enter,没有实现真正的"暂停循环执行、等待Enter恢复"的效果。
- 数据库连接未使用
using语句,存在资源泄漏风险。
下面是修正后的完整代码,实现了**按下P键暂停循环执行(停止定时器),按下Enter键恢复循环(重启定时器)**的功能:
using System; using System.Data; using System.Data.SqlClient; using System.Timers; namespace pauza { internal class Program { static Timer timer = new Timer(10000); // 控制循环暂停/恢复的标志位 static bool isPaused = false; static void Main(string[] args) { // 只注册一次定时器事件,避免重复触发 timer.Elapsed += Timer_Elapsed; string connectionString = "Data Source=XXX.XX.XX.X;Initial Catalog=DEMO;User ID=sa;Password=demo1234;MultipleActiveResultSets=true"; // 使用using自动释放数据库连接资源 using (SqlConnection conn00 = new SqlConnection(connectionString)) { string sql00 = "SELECT [GidWZ] FROM [DEMO].[dbo].[WWZ]"; SqlCommand cmd00 = new SqlCommand(sql00, conn00); conn00.Open(); SqlDataAdapter adapter00 = new SqlDataAdapter(cmd00); DataTable dt00 = new DataTable(); adapter00.Fill(dt00); timer.Start(); while (dt00.Rows.Count > 0) { // 检查是否有按键输入,非阻塞 if (Console.KeyAvailable) { ConsoleKeyInfo cki = Console.ReadKey(true); if (cki.Key == ConsoleKey.P && !isPaused) { isPaused = true; timer.Stop(); Console.WriteLine("\nProcess Is Paused, Press 'Enter' to Continue..."); } else if (cki.Key == ConsoleKey.Enter && isPaused) { isPaused = false; timer.Start(); Console.WriteLine("\nResuming Process..."); } } // 如果处于暂停状态,跳过本次循环的业务逻辑 if (isPaused) { continue; } try { // 使用using管理conn01,自动关闭释放 using (SqlConnection conn01 = new SqlConnection(connectionString)) { string sql01 = "SELECT top 1 [GidWZ], [CodePost] FROM [DEMO].[dbo].[WWZ]"; SqlCommand cmd01 = new SqlCommand(sql01, conn01); conn01.Open(); using (SqlDataReader reader01 = cmd01.ExecuteReader()) { if (reader01.Read()) { string obinumer00 = reader01.GetValue(0).ToString(); string obinumer01 = reader01.GetValue(1).ToString(); // 这里写你的业务逻辑代码 Console.WriteLine($"Processing: GidWZ={obinumer00}, CodePost={obinumer01}"); } } } } catch (Exception ex) { Console.WriteLine("\nError: " + ex.Message); } finally { // 注意:SessionID需要你提前定义和赋值 // if (cdn_api.Logout(SessionID) != 0) // { // Console.WriteLine("\nNo data to process"); // } // else // { // Console.WriteLine("\nSession closed"); // } } // 可根据需要添加循环延迟,避免过度占用CPU System.Threading.Thread.Sleep(100); } } timer.Stop(); timer.Dispose(); Console.WriteLine("\nProcess completed. Press any key to exit."); Console.ReadKey(); } private static void Timer_Elapsed(object sender, ElapsedEventArgs e) { Console.WriteLine($"\nCurrent time: {DateTime.Now}"); } } }
关键改进点说明
- 标志位控制暂停状态:用
isPaused变量控制循环是否执行业务逻辑,暂停时跳过业务代码。 - 非阻塞按键监听:使用
Console.KeyAvailable检查是否有按键输入,避免阻塞循环执行。 - 定时器事件只注册一次:在Main开头只注册一次
Timer_Elapsed,防止重复触发。 - 数据库连接优化:使用
using语句自动管理连接、DataReader等资源,避免泄漏。 - 逻辑结构调整:将按键监听放在循环开头,优先处理暂停/恢复指令,再执行业务逻辑。
内容的提问来源于stack exchange,提问作者coolthx
相关产品推荐
相关产品推荐

