Мне кажется неприятным использовать Timeout
из-за исключений.
Я предпочитаю вводить значение в последовательность, которую я могу использовать для завершения последовательности.Если моя последовательность, например, выдает неотрицательные числа, то, если я введу -1
, я знаю, чтобы завершить последовательность.
Вот пример:
Начните с этой наблюдаемой, которая генерирует силы2, начиная с 1, и также задерживает создание каждого значения на количество миллисекунд ожидающего значения.
Observable
.Generate(1, x => true, x => 2 * x, x => x, x => TimeSpan.FromMilliseconds(x))
То есть 1, 2, 4, 8 и т. д., становится все медленнее и медленнее.
Теперь я хочу остановить эту последовательность, если нет значений для 3.0
секунд, тогда я могу сделать это:
.Select(x => Observable.Timer(TimeSpan.FromSeconds(3.0)).Select(y => -1).StartWith(x))
.Switch()
.TakeWhile(x => x >= 0)
Если я запусту эту последовательность, я получу такой вывод:
1
2
4
8
16
32
64
128
256
512
1024
2048
Последовательность вот-вот выдаст 4096
, но сначала она ждет 4096
миллисекунд, чтобы получить это значение - тем временем Observable.Timer(TimeSpan.FromSeconds(3.0))
запускает и выводит -1
, таким образом останавливая последовательность.
Ключевой частью этого запроса является использование Switch
.Он принимает IObservable<IObservable<T>>
и создает IObservable<T>
, только подписываясь на последнюю внешнюю наблюдаемую и отписываясь от предыдущей.
Итак, в моем запросе каждое новое значение, созданное последовательностью, останавливается и перезапускается.Timer
.
В вашем случае ваша наблюдаемая будет выглядеть так:
characteristic
.WhenNotificationReceived()
.Select(result => BitConverter.ToString(result.Data).Replace("-", ""))
.Select(x => Observable.Timer(TimeSpan.FromSeconds(1.0)).Select(y => (string)null).StartWith(x))
.Switch()
.TakeWhile(x => x != null)
.Subscribe(rfidPlayer);