C#中是否有when()语句或等效机制可等待属性变为true?
在C#中实现「等待属性变为true」的方案
当然有啦!在C#里,你完全可以实现类似你说的when语句功能——也就是等待某个属性变为true,而不是像if那样只做单次检查。下面给你几个实用的实现方式,根据你的场景选就行:
1. 简单轮询(适合快速实现、低性能要求场景)
这是最直观的方式,通过异步循环+延迟检查属性状态,避免阻塞线程:
public async Task WaitForPropertyToBeTrueAsync() { // 循环检查,直到属性变为true while (!YourTargetProperty) { // 每隔100毫秒检查一次,可根据需求调整间隔 await Task.Delay(100); } // 这里写属性变为true后要执行的逻辑 Console.WriteLine("属性已经变为true啦!"); }
⚠️ 注意:别直接写死循环(没有Task.Delay),那样会占满CPU资源。另外如果担心永远等不到,可以加超时判断:
public async Task<bool> WaitForPropertyToBeTrueWithTimeoutAsync(int timeoutMilliseconds) { var startTime = DateTime.UtcNow; while (!YourTargetProperty) { if ((DateTime.UtcNow - startTime).TotalMilliseconds > timeoutMilliseconds) { return false; // 超时返回失败 } await Task.Delay(100); } return true; // 成功等到属性变为true }
2. 事件驱动等待(高效、无轮询,适合性能敏感场景)
如果不想用轮询,可以用ManualResetEventSlim(或者AutoResetEvent)来实现事件触发式等待,只有当属性变为true时才会唤醒等待的线程:
首先在类里定义一个信号量字段,并在属性的setter里触发信号:
// 初始化时设为未触发状态 private readonly ManualResetEventSlim _propertyTrigger = new ManualResetEventSlim(false); private bool _yourTargetProperty; public bool YourTargetProperty { get => _yourTargetProperty; set { _yourTargetProperty = value; // 当属性变为true时,触发信号唤醒等待的线程 if (value) { _propertyTrigger.Set(); } } }
然后写等待方法,支持同步和异步两种版本:
// 同步版本(会阻塞当前线程) public void WaitForPropertyToBeTrue() { _propertyTrigger.Wait(); // 属性变为true后的逻辑 } // 异步版本(不会阻塞线程,推荐在UI或异步场景用) public async Task WaitForPropertyToBeTrueAsync(CancellationToken cancellationToken = default) { await _propertyTrigger.WaitAsync(cancellationToken); // 属性变为true后的逻辑 }
用完后记得释放资源(比如在类的Dispose方法里调用_propertyTrigger.Dispose())。
3. 响应式编程(Rx.NET,适合复杂属性监听场景)
如果你的项目本身用了响应式编程,或者需要监听多个属性变化,可以用Rx.NET来优雅实现:
首先安装NuGet包System.Reactive,然后用WhenAnyValue监听属性变化,直到它变为true:
using System.Reactive.Linq; // 假设你的类实现了INotifyPropertyChanged接口(MVVM项目常用) public async Task WaitForPropertyToBeTrueAsync() { // 监听属性变化,直到它变为true,取第一个符合条件的结果 await this.WhenAnyValue(x => x.YourTargetProperty) .Where(isTrue => isTrue) .Take(1) .ToTask(); // 属性变为true后的逻辑 }
这种方式非常灵活,还能扩展成监听多个属性、添加过滤条件等场景。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

