如何在“可重复时间”观察中修复竞争条件?

问题描述 投票:0回答:1

输入是一个可观察的,每次出现问题时都会产生一个值。

作为输出,我想要一个observable,如果问题存在较长时间,它会产生一个值。换句话说,如果最后一个问题已经过时,我想“重置”输出可观察(不产生值)。

我的解决方案

// 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在相反的情况下,99.9%的时间是true

(PS:从开始就有状态值,我们可能会添加.StartWith(true),但这与竞争条件无关。)

c# observable system.reactive race-condition throttling
1个回答
2
投票

第一个可观察的清洁方法如下:

var okStatusObservable2 = input
    .Select(_ => Observable.Return(true).Delay(longerTime).StartWith(false))
    .Switch();

说明:对于每个input消息,生成一个以false开头的observable,并在longerTime生成一个true之后。 Switch意味着如果你有一个新的observable,只需切换到它,这将排除最后的全明确的true

对于你的第二个可观测量,除非longerTime在两个可观测量之间不同,否则第一个可观测量中的每个第一个false将在第二个观测值中产生false。这是你的意图吗?

此外,你的Where搞砸了(应该是.Where(b => !b).Where(b => b == false)..Where(_ => false)将总是评估为false,什么都不返回。

除此之外,我认为你的解决方案是合理的。

© www.soinside.com 2019 - 2024. All rights reserved.