Вы должны использовать .Switch()
для ситуаций, когда поступающее новое значение заставляет вас игнорировать результаты любых предыдущих введенных значений.
Вот запрос, который вам нужен:
IObservable<Unit> query =
source
.Select(x => x > 100.0)
.DistinctUntilChanged()
.Select(x => x
? Observable.Timer(TimeSpan.FromSeconds(5.0)).Select(x => Unit.Default)
: Observable.Never<Unit>())
.Switch();
Комбинация .Select(x => x >= 100.0).DistinctUntilChanged()
изменяет источник на IObservable<bool>
, который срабатывает только тогда, когда датчик переворачивает между x > 100.0
и x <= 100.0
- true
при превышении 100 ° C и ложном для 100 ° C или меньше.
Теперь мы превращаем IObservable<bool>
в IObservable<IObservable<Unit>>
. Это наблюдаемая, которая производит другие наблюдаемые. Когда мы получаем true
, я хочу вернуть IObservable<Unit>
, который срабатывает через 5.0
секунд, а когда мы получаем false
, я хочу вернуть наблюдаемое, которое вообще не возвращает значения.
Это то, что делает .Select(x => x ? Observable.Timer(TimeSpan.FromSeconds(5.0)).Select(x => Unit.Default) : Observable.Never<Unit>())
.
Наконец, мы вставляем .Switch()
, который изменяет IObservable<IObservable<Unit>>
на IObservable<Unit>
, производя только значения, основанные на последнем внутреннем произведенном IObservable<Unit>
. Другими словами, если датчик переворачивается сверху 100.0
ниже снова через 5.0
секунд, то он игнорирует значение Observable.Timer(TimeSpan.FromSeconds(5.0))
и ожидает значения от Observable.Never<Unit>()
. Если оно превышает 100.0
более чем на 1036 *, то срабатывает Observable.Timer(TimeSpan.FromSeconds(5.0))
и вы получаете Unit
, полученный по вашему запросу.
Это ведет себя именно так, как вы хотели.
Вот несколько более простая версия запроса:
IObservable<Unit> query =
source
.Select(x => x > 100.0)
.DistinctUntilChanged()
.Select(x => x
? Observable.Timer(TimeSpan.FromSeconds(5.0))
: Observable.Never<long>())
.Switch()
.Select(x => Unit.Default);