如何在执行后续代码前正确等待条件满足?能否用自定义事件替代循环?
替代忙等待的方案及自定义事件实现
原代码的问题
你当前的while空循环属于忙等待,会持续占用CPU资源,线程一直在空转浪费性能,这是非常不推荐的实现方式。
方案一:使用ManualResetEventSlim(轻量推荐方案)
这是.NET原生的同步原语,专门用于等待条件触发,比自定义事件更简洁高效:
private ManualResetEventSlim _waitHandle = new ManualResetEventSlim(false); private bool _conditionA; private bool _conditionB; // 其他任务中设置条件的方法 public void SetConditionA(bool value) { _conditionA = value; CheckAndSignal(); } public void SetConditionB(bool value) { _conditionB = value; CheckAndSignal(); } private void CheckAndSignal() { if (_conditionA && _conditionB) { _waitHandle.Set(); // 条件满足,触发信号 } } private async Task HandleData() { await Task.Run(() => _waitHandle.Wait()); // 等待信号,无空转 // 执行后续步骤 // ... }
方案二:自定义事件实现
完全可以用自定义事件实现该逻辑,核心是在条件变更时触发检查,满足条件后通知后续代码执行:
private bool _conditionA; private bool _conditionB; private readonly object _lockObj = new object(); private TaskCompletionSource<bool> _tcs; // 定义条件变更事件 private event Action ConditionUpdated; // 用属性封装条件,赋值时触发事件 private bool ConditionA { get => _conditionA; set { lock (_lockObj) _conditionA = value; ConditionUpdated?.Invoke(); } } private bool ConditionB { get => _conditionB; set { lock (_lockObj) _conditionB = value; ConditionUpdated?.Invoke(); } } private async Task HandleData() { _tcs = new TaskCompletionSource<bool>(); ConditionUpdated += CheckConditions; // 先检查一次,避免条件已满足但未触发事件 CheckConditions(); await _tcs.Task; ConditionUpdated -= CheckConditions; // 清理事件订阅 // 执行后续步骤 // ... } private void CheckConditions() { lock (_lockObj) { if (ConditionA && ConditionB) { _tcs.TrySetResult(true); // 条件满足,通知后续代码执行 } } } // 其他任务中设置条件的示例 public void UpdateConditionA() => ConditionA = true; public void UpdateConditionB() => ConditionB = true;
自定义事件方案说明
- 用属性封装条件变量,确保赋值时触发变更事件
- 通过
TaskCompletionSource实现异步等待,符合async方法的非阻塞设计 - 加锁是为了避免多线程下的竞态问题,保证条件检查和赋值的线程安全
两种方案都能彻底解决原代码的忙等待问题,大幅提升资源利用率。
内容的提问来源于stack exchange,提问作者AnonymousKKYY
相关产品推荐
相关产品推荐

