给定一个可观察的源,通过轮询低级设备的状态(a的变化)生成...
// observable source metacode:
IObservable<DeviceState> source = Observable.Interval(TimeSpan.FromSeconds(0.5))
.Select(tick => new DeviceState(_device.ReadValue()))
.DistinctUntilChanged();
Run Code Online (Sandbox Code Playgroud)
......以及更新UI的消费者......
// UI metacode:
service.GetObservableDeviceStates()
.Subscribe(state => viewModel.CurrentState = state.ToString());
Run Code Online (Sandbox Code Playgroud)
...我需要在x秒的源"不活动"之后执行自定义操作,而不会中断对源的订阅.像这样的东西:
// UI metacode:
service.GetObservableDeviceStates()
.DoOnTimeout(TimeSpan.FromSeconds(x), () => viewModel.CurrentState = "Idle")
.Subscribe(state => viewModel.CurrentState = state.ToString());
Run Code Online (Sandbox Code Playgroud)
什么是最佳做法?想到的可能解决方案是(我是Rx noob):
当没有任何变化(而不是使用DistinctUntilChanged)并在UI代码上处理它时,返回一些特殊的"服务端":
service.GetObservableDeviceStates().Subscribe(state => viewModel.CurrentState = state.Special?"Idle":state.ToString());
编辑:如答案中所述,解决方案是:
service.GetObservableDeviceStates()
.Do(onNext)
.Throttle(TimeSpan.FromSeconds(x))
.Subscribe(onTimeout);
Run Code Online (Sandbox Code Playgroud)
EDIT2(警告)
如果onNext和onTimeout更新UI组件,为了避免CrossThreadExceptions需要两个 ObserveOn(uiSynchronizationContext),因为Throttle在另一个线程上工作!
service.GetObservableDeviceStates()
.ObserveOn(uiSynchronizationContext)
.Do(onNext)
.Throttle(TimeSpan.FromSeconds(x))
.ObserveOn(uiSynchronizationContext)
.Subscribe(onTimeout);
Run Code Online (Sandbox Code Playgroud) 寻找一种干净的方法来转换源Observable以null在一段时间内不发出项目后发出单个(或标记值).
例如,如果源可观察的发射1, 2, 3然后在发射之前停止发射10秒,4, 5, 6我希望发射的项目是1, 2, 3, null, 4, 5, 6.
用例用于在UI中显示值,其中显示的值应变为破折号-或者N/A最后发出的值是陈旧/旧的.
我查看了timeout运算符,但它终止Observable了超时发生的时间,这是不可取的.
使用RxJava.
我有一个返回可观察对象的方法。这个 observable 应该(如果 evetything 正常工作)每秒发布一个值。我想要做的是让它发布一些自定义警报值,如果某个时间过去了而没有输出。
private IObservable<string> GetStatus()
{
return statusProvider
.Subscribe(statusKey) //returns an IObservable<string>
.Select(st => st.ToUpper())
.DistinctUntilChanged()
.TakeUntil(disposed)
.Replay(1)
.RefCount();
}
Run Code Online (Sandbox Code Playgroud)
是否有一种简单的方法可以让我修改上述内容,以便如果 30 秒内没有状态更新,则 statusProvider 发布“坏”,然后如果更新确实在此之后进入,它会像往常一样发布并且计时器是再次重启到30秒?