设置如下:有一个联邦远程服务,该服务返回特定值正确或不正确.我们可以根据需要发送请求,每个请求最多可以发送50个到远程服务.
由于我们只需要使用正确的值,并且可能的值的集合很小(〜700),因此我们只可以发送15个左右的50个批处理请求,而正确的值将成为结果集的一部分.因此,我使用了以下代码:
Observable
.Range(0, requests.Count)
.Select(i => Observable.FromAsync(async () =>
{
responses.Add(await client.FederalService.VerifyAsync(requests[i]));
Console.Write(".");
}))
.Merge(8)
.Wait();
但是-我对此不满意的是,如果较早的请求之一具有正确的值,那么在服务浪费的时间里,我仍然会尽一切可能.我正在尝试使其尽快运行.我知道退出条件(响应代码是从1到99,50-59之间的任何响应代码都表示该值是“正确”).
有没有一种方法可以使此代码更智能一些,从而使请求数量最少?不幸的是,我们正在验证的值是均匀分布的,因此对请求进行排序不会产生任何作用(我知道).
解决方法:
您应该考虑使用FirstAsync
method here:
The secret in our example is the
FirstAsync
method. We are actually awaiting the first result returned by our observable and don’t care about any further results.
所以您的代码可能像这样:
await Observable
.Range(0, requests.Count)
.Select(i => Observable.FromAsync(async () =>
{
responses.Add(await client.FederalService.VerifyAsync(requests[i]));
Console.Write(".");
}))
.FirstAsync()
.Subscribe(Console.WriteLine);
> System.Reactive.Linq.ObservableImpl.Defer`1[System.Reactive.Unit]
Rx and Await: Some Notes文章提供了一些使用类似方法的技巧.例如,您有一个FirstAsync的重载,可以作为LINQ’方法First进行过滤:
await Observable
.Range(0, requests.Count)
.Select(i => Observable.FromAsync(async () =>
{
responses.Add(await client.FederalService.VerifyAsync(requests[i]));
Console.Write(".");
}))
.FirstAsync(r => /* do the check here */)
.Subscribe(Console.WriteLine);