输入是可观察的,每次出现问题时都会产生一个值。
作为输出,我希望如果问题存在时间较长,则可观察值会产生一个值。换句话说,如果最后一个问题已过时,我想“重置”可观察的输出(不产生值)。
我的解决方案:
// first get an observable producing statusOk values (true = ok, false = not ok)
var okStatusObservable = input.Select(_ => true).Throttle(longerTime)
.Merge(input.Select(_ => false));
// we only want event if statusOk=false for a longer time
var outputObservable = okStatusObservable
.DistinctUntilChanged() // only changes
.Throttle(evenLongerTime) // wait for stable status
.Where(_ => _ == false); // only interested in bad status
我认为okStatusObservable
可能包含竞争条件:如果输入在恰好longerTime
的时间间隔接收事件,则第二个合并部分(Select
/ false
)会产生在第一部分(Select
+ Throttle
/ true
)之前的布尔值,那么这将导致okStatus的概率为true
99.9%的时间是正确的,而相反的情况是正确的。
(PS:要从一开始就具有状态值,我们可以添加.StartWith(true)
,但这与种族状况无关紧要。)
答案 0 :(得分:2)
第一个可观察到的更干净的方法如下:
var okStatusObservable2 = input
.Select(_ => Observable.Return(true).Delay(longerTime).StartWith(false))
.Switch();
说明:对于每条input
消息,产生一个以false开头的observable,然后在longerTime
之后产生一个true。 Switch
意味着如果您有一个新的可观察对象,只需切换到它即可,这将最终排除所有清晰的true
。
对于您的第二个可观察物,除非两个可观察物之间的longerTime
不同,否则第一个可观察物的每个第一个false
都会在第二个可观察物中产生false
。那是你的意图吗?
此外,您的Where
被搞砸了(应该是.Where(b => !b)
或.Where(b => b == false)
。.Where(_ => false)
始终会返回false,不返回任何内容。
除此之外,我认为您的解决方案是正确的。