Rx.NET регулирование с отменой - PullRequest
0 голосов
/ 25 октября 2018

У меня есть вопрос, похожий на этот .Мне нужно обработать последовательность событий пользовательского ввода (поисков) следующим образом:

  • дросселировать каждую поисковую фразу с N-миллисекундами
  • отменить ранее выполненный поиск, если поисковая фраза изменилась (и скоро начнется новый поиск)
  • применить только последний поиск

Кажется, мой код работает почти так, кроме отмены.

Observable.FromEventPattern<TextChangedEventArgs>(
    handler => SearchBox.TextChanged += handler,
    handler => SearchBox.TextChanged -= handler)
.ObserveOn(SynchronizationContext.Current)
.Select(GetSearchQuery)
.Throttle(TimeSpan.FromMilliseconds(MinimumSearchIntervalMiliseconds))
.DistinctUntilChanged()
.Subscribe(ExecuteSearch, () => { });

string GetSearchQuery(EventPattern<TextChangedEventArgs>) возвращает строку поиска, а void ExecuteSearch(string) выполняет поиск.

Почему-то я не могу найти расширение Switch(), упомянутое во всех ответах на SO ...

Я используюSystem.Reactive и System.Reactive.Linq в версии 4.0.0

Я полагаю, что Select() и Subscribe() в этой форме не лучшее решение в приведенном выше коде.Вероятно, они должны работать на Task s ...

Есть идеи, как улучшить описанный выше конвейер для поддержки отмены при необходимости?

1 Ответ

0 голосов
/ 25 октября 2018

Я предполагаю здесь, но вы, вероятно, ExecuteSearch отправляют строку поиска, получаете результаты, а затем привязываете их к пользовательскому интерфейсу.Разделите ExecuteSearch, чтобы в идеале вернуть IObservable<Results> или Task<Results>, и новую функцию public void ApplySearchResults(Results r) для обработки привязки пользовательского интерфейса.

Как только вы это сделаете, это должно работать:

Observable.FromEventPattern<TextChangedEventArgs>(
    handler => SearchBox.TextChanged += handler,
    handler => SearchBox.TextChanged -= handler)
.ObserveOn(SynchronizationContext.Current)
.Select(GetSearchQuery)
.Throttle(TimeSpan.FromMilliseconds(MinimumSearchIntervalMiliseconds))
.DistinctUntilChanged()
.Select(ExecuteSearch /* .ToObservable() if it returns Task<Results>/*)
.Switch()
.Subscribe(ApplyResults, () => { })

.Switch работает на IObservable<IObservable<T>>.У вас не было двойной наблюдаемой, только одной, именно поэтому вы ее не видели.

...