gpt4 book ai didi

c# - 使用reactui + throttle 调用异步方法的最佳方法是什么

转载 作者:太空狗 更新时间:2023-10-30 00:04:49 24 4
gpt4 key购买 nike

我正在尝试使用Rx + ReactiveUI解决我的第一个任务,并且正在寻找解决任务的最佳实践,并显示一个输入框,该框将在用户开始输入内容时立即显示建议。

根据以下代码示例,异步加载建议的最佳方法是什么?使用Subscribe还是使用Select Many?还是在这两个之间有更好的方法来做到这一点?

     this.SearchTerms = this.ObservableForProperty(x => x.SearchTerm)
.Throttle(SuggestionThrottle, RxApp.MainThreadScheduler)
.Value()
.SelectMany(async s => await this.LoadSearchSuggestions(s)); // 1st Possibility

this.SearchTerms.Subscribe(this.LoadSearchSuggestions); // 2nd Possibility

最佳答案

您必须以任何一种方式调用Subscribe

Rx中的查询使用惰性评估,这意味着仅定义查询不会启动查询。惰性评估允许您通过有条件地应用运算符来构建查询,仅定义一次查询并将其存储在字段中以供以后使用,或者在不引起任何副作用的情况下传递引用,直到调用Subscribe为止。

如果不调用Subscribe,您的查询将保持不事件状态。
Subscribe通过传递给可观察到的IObserver<T>来激活查询,或者您可以使用其重载来单独提供OnNextOnError和/或OnCompleted处理程序,Rx会为您将其转换为IObserver<T>。接收查询通知的是IObserver<T>
Subscribe有一个无参数的重载,该重载在内部使用静默的观察器,旨在仅出于其副作用而开始查询。例如,如果您要使用SelectMany来完成所有加载建议的工作,而又不需要单独的IObserver<T>,则可以通过调用Subscribe的无参数重载来启动查询。

在大多数情况下,不应使用Subscribe的无参数重载。 Subscribe的要点是,传递给它的IObserver<T>(或各个处理程序)旨在引起查询的副作用。通过仅在SubscribeDo运算符中引起副作用,查询就更容易推论和维护。

但是,在一种相当普遍的情况下,使用Subscribe的无参数重载是有意义的:如果查询的副作用是由异步方法引起的,则最好将SelectManySubscribe的无参数重载一起使用。

原因很简单:SelectMany是顺序组合运算符,它使您可以在查询内部将异步方法作为顺序步骤来调用。因此,SelectMany将取消订阅与取消异步计算联系起来。取消订阅(由从对IDisposble的调用返回的Subscribe表示)导致由CancellationToken运算符的特殊异步重载提供的SelectMany发出信号以取消。您的异步方法可以监视CancellationToken以便尽早退出其计算。

没有Subscribe重载可以接受异步观察者,由此OnNext返回Task。但是,即使您要在OnNext处理程序中调用返回空值的异步方法,在处理预订时也不会发出异步方法的信号。

请注意,无论如何,您的两个代码示例都略有错误。第一个示例不需要asyncawait关键字。如上所述,有SelectMany的特殊重载可以接受Task<T>返回选择器函数,而其他重载也可以为该函数提供CancellationToken。您可能应该使用后者。

您的第二个示例不应编译,假设LoadSearchSuggestions返回Task。 (除非您所引用的ReactiveUI库或其他某个库提供了Subscribe的重载,该重载接受了Task -returning函数,在这种情况下,您必须查阅其文档。)

除非后者,并假设其余查询正确无误,这是您应该做的:

this.SearchTerms = this.ObservableForProperty(x => x.SearchTerm)
.Throttle(SuggestionThrottle, RxApp.MainThreadScheduler)
.Value()
.SelectMany(LoadSearchSuggestionsAsync)
.Subscribe();
LoadSearchSuggestionsAsync的定义如下:
async Task<Unit> LoadSearchSuggestionsAsync(string term, CancellationToken cancel)
{
...
return Unit.Default;
}

注意 Unit表示Rx中的void。这是必需的,因为返回非通用 Task的异步方法不能与 SelectMany一起使用。如果您有实际的数据要返回,则只需将 Unit替换为数据类型。然后,您还可以将 OnNext处理函数传递给 Subscribe并使用返回值执行某些操作,例如日志记录。

关于c# - 使用reactui + throttle 调用异步方法的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27618401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com