给定一个可观察的源,通过轮询低级设备的(a的变化)状态生成......
// observable source metacode:
IObservable<DeviceState> source = Observable.Interval(TimeSpan.FromSeconds(0.5))
.Select(tick => new DeviceState(_device.ReadValue()))
.DistinctUntilChanged();
...以及更新 UI 的消费者...
// UI metacode:
service.GetObservableDeviceStates()
.Subscribe(state => viewModel.CurrentState = state.ToString());
...我需要在源“不活动”x 秒后执行自定义操作,而不会中断对源的订阅。像这样的东西:
// UI metacode:
service.GetObservableDeviceStates()
.DoOnTimeout(TimeSpan.FromSeconds(x), () => viewModel.CurrentState = "Idle")
.Subscribe(state => viewModel.CurrentState = state.ToString());
最佳实践是什么?想到的可能解决方案是(我是 Rx 菜鸟):
- 缓冲区(即使它不那么可读)
- 解决这个超时重载;
当没有任何变化时返回一些特殊的“服务端”(而不是使用 DistinctUntilChanged)并在 UI 代码上处理它:
service.GetObservableDeviceStates() .Subscribe(state => viewModel.CurrentState = state.Special ? "Idle" : state.ToString());
编辑:如答案中所述,解决方案是:
service.GetObservableDeviceStates()
.Do(onNext)
.Throttle(TimeSpan.FromSeconds(x))
.Subscribe(onTimeout);
EDIT2(警告)
如果 onNext 和 onTimeout 更新 UI 组件,为了避免 CrossThreadExceptions需要两个ObserveOn(uiSynchronizationContext),因为 Throttle 在另一个线程上工作!
service.GetObservableDeviceStates()
.ObserveOn(uiSynchronizationContext)
.Do(onNext)
.Throttle(TimeSpan.FromSeconds(x))
.ObserveOn(uiSynchronizationContext)
.Subscribe(onTimeout);