如何让C#的foreach循环暂停等待点击事件后再执行下一轮迭代
问题解决方案
你的思路逻辑上是成立的,但如果是通过循环轮询布尔变量的方式实现等待,会产生无意义的CPU占用,更优的方案是使用TaskCompletionSource实现基于异步回调的等待,完美适配async/await语法,无额外性能开销,也不会阻塞UI线程。
具体实现代码
第一步:窗体类声明对应字段
// 窗体类内声明字段 private TaskCompletionSource<bool> _nextClickedTcs; // 注意:Cef.Initialize 全局只需要初始化一次,不要放在循环里重复调用
第二步:改造循环逻辑(所在方法需标记为async)
// Cef初始化提前到循环外执行,只执行一次 Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); foreach (string site in sites) { // 每轮循环重置信号源 _nextClickedTcs = new TaskCompletionSource<bool>(); browser = new ChromiumWebBrowser(site); browser.AddressChanged += OnBrowserAddressChanged; panelBrowserMain.Controls.Add(browser); browser.Dock = DockStyle.Fill; browserMain.Text = site; // 等待下一步按钮点击,不会阻塞UI线程 await _nextClickedTcs.Task; // 处理当前browser的清理逻辑,避免内存泄漏 panelBrowserMain.Controls.Remove(browser); browser.Dispose(); }
第三步:下一步按钮点击事件触发信号
private void btnNext_Click(object sender, EventArgs e) { // 通知等待的循环继续执行 _nextClickedTcs?.SetResult(true); }
方案优势
- 没有轮询开销,完全基于事件回调触发,等待阶段CPU占用为0
- 符合WinForm异步编程规范,等待过程中UI完全响应,不会出现假死
- 逻辑清晰,不需要手动维护布尔变量的重置状态,避免出现逻辑bug
内容的提问来源于stack exchange,提问作者logosapp
相关产品推荐
相关产品推荐

