将列表分成 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)
,这意味着代码将等待每个连接,就像同步代码一样。
如果你想使用异步代码,对于这个例子,我们可能会得到 Task
或 Task
列表,我们将从 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());
我有一个 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)
,这意味着代码将等待每个连接,就像同步代码一样。
如果你想使用异步代码,对于这个例子,我们可能会得到 Task
或 Task
列表,我们将从 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());