[英]How can I fix race condition in this “reset after time” observable?
Input is an observable that produces a value each time a problem occurs. 输入是可观察的,每次出现问题时都会产生一个值。
As output I want an observable that produces a value if problems exist for a longer time. 作为输出,我希望如果问题存在时间较长,则可观察值会产生一个值。 In other words I want to "reset" the output observable (not produce values) if the last problem is outdated.
换句话说,如果最后一个问题已过时,我想“重置”可观察的输出(不产生值)。
My solution: 我的解决方案:
// 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
I think the okStatusObservable
might contain a race condition: If input receives events at time interval of exactly longerTime
and second merge part ( Select
/ false
) would produce a boolean before the first part ( Select
+ Throttle
/ true
) then this would result in okStatus to be true
99.9% of the time where the opposite would be correct. 我认为
okStatusObservable
可能包含竞争条件:如果输入以恰好longerTime
时间间隔接收事件,并且第二个合并部分( Select
/ false
)会在第一个部分( Select
+ Throttle
/ true
)之前产生一个布尔值,那么这将导致okStatus是true
的时间,其中所述对面将是正确99.9%。
(PS: to have status value from beginning, we might add .StartWith(true)
but that doesn't matter regarding race condition.) (PS:要从一开始就具有状态值,我们可以添加
.StartWith(true)
但这与竞争条件无关紧要。)
A cleaner way to do the first observable is as follows: 进行第一个可观察的更干净的方法如下:
var okStatusObservable2 = input
.Select(_ => Observable.Return(true).Delay(longerTime).StartWith(false))
.Switch();
Explanation: For each input
message, produce an observable that starts with a false, and after longerTime
produces a true. 说明:对于每个
input
消息,产生一个以false开头的observable,然后在longerTime
之后产生一个true。 The Switch
means that if you have a new observable, just switch to it, which would exclude the all-clear true
at the end. Switch
表示如果您有一个新的可观察值,只需切换到它,这将在最后排除所有明显的true
。
For your second observable, unless longerTime
differs between the two observables, every first false
in the first observable will result in a false
in the second. 对于您的第二个可观察
longerTime
,除非两个可观察longerTime
之间的longerTime
有所不同,否则第一个可观察longerTime
每个第一个false
将导致第二个可观察longerTime
中的false
。 Is that your intention? 那是你的意图吗?
Also, your Where
is messed up (should be .Where(b => !b)
or .Where(b => b == false)
. .Where(_ => false)
will always evaluate to false returning nothing. 另外,您的
Where
搞砸了(应该是.Where(b => !b)
或.Where(b => b == false)
。. .Where(_ => false)
将始终为false,不返回任何内容。
Other than that, I think your solution is sound. 除此之外,我认为您的解决方案是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.