将列表分成 3 部分以加速异步功能

Cut a list in 3 parts to speed up Async function

我有一个 linq 表达式可以完成这项工作:

var y = docs.ToList()
var res = y.Select(async b => await loadAgence(b.url))
           .Select(x => x.Result)
    :
    :
private async Task<BsonDocument? doc, int status, bool iSSucess) loadAgence(string url)
{
    var (docs, status, isSuccess) = await Helper.API_GetDocument(url);
    return (isSuccess ? docs : null, status, isSuccess)
}

this job takes 3 minutes to execute 900 loops (900 Call API)

我会把合集分成 3 部分,将时间间隔除以 3

var res1 = y.Skip(0).Take(300).Select(async b => await loadAgence(b.url))
            .Select(x => x.Result)
var res2 = y.Skip(300).Take(300)Select(async b => await loadAgence(b.url))
            .Select(x => x.Result)
var res3 = y.Skip(600).Take(300)Select(async b => await loadAgence(b.url))
            .Select(x => x.Result)

但是当然每个部分都被阻止了,我该如何解决这个问题?

我曾尝试将 WhenAll 与列表集合(res1 到 res3)一起使用,但它正在等待 IEnumerable<Task> 而我有 List<IEnumerable<Task<BsonDocument? doc, int status, bool iSuccess)>>> 所以它拒绝转换..

可以吗?

but of course each part is blocked, how i could resolve this problem?

因为您对 Task 列表的每个部分使用 .Select(x => x.Result),这意味着代码将等待每个连接,就像同步代码一样。

如果你想使用异步代码,对于这个例子,我们可能会得到 TaskTask 列表,我们将从 res1、[=18= 得到 IEnumerable<Task(BsonDocument? doc, int status, bool iSSucess)>> ],res3

var res1 = y.Skip(0).Take(300).Select(async b => await loadAgence(b.url));
var res2 = y.Skip(300).Take(300).Select(async b => await loadAgence(b.url));
var res3 = y.Skip(600).Take(300).Select(async b => await loadAgence(b.url));

不幸的是Task.WhenAll可能不支持多个IEnumerable<Task>数组参数,所以我们可以尝试使用List<Task<(BsonDocument? doc, int status, bool iSSucess)>>来追加所有列表然后Task.WhenAll

var tasks = new List<Task<(BsonDocument? doc, int status, bool iSSucess)>>();   
tasks.AddRange(res1);   
tasks.AddRange(res2);   
tasks.AddRange(res3);  

var result = await Task.WhenAll(tasks.ToArray());