Rx.NET取消限制

时间:2018-10-25 13:57:49

标签: task-parallel-library system.reactive rx.net

我有一个类似于this one的问题。我需要通过以下方式处理一系列用户输入事件(搜索):

  • 用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)运行搜索。

由于某种原因,我找不到所有关于SO的答案中提到的Switch()扩展名...

我正在使用System.Reactive版的System.Reactive.Linq4.0.0

我猜这种形式的Select()Subscribe()不是上面代码中的最佳解决方案。它们可能应该在Task上运行...

有什么主意我该如何改善上述管道以支持按需取消?

1 个答案:

答案 0 :(得分:2)

我在这里猜测,但是您可能有ExecuteSearch发送搜索字符串,获取结果,然后将其绑定到UI。拆分ExecuteSearch以理想地返回IObservable<Results>Task<Results>和一个新函数public void ApplySearchResults(Results r)来处理UI绑定。

一旦有了,它应该可以工作:

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>>。您没有双重可观察到的东西,只有一个,这就是为什么您没有看到它的原因。