Ari*_*her 1 c# linq select asynchronous async-await
阅读本文后: 在Parallel.ForEach中嵌套等待
我试着做以下事情:
private static async void Solution3UsingLinq()
{
var ids = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
var customerTasks = ids.Select(async i =>
{
ICustomerRepo repo = new CustomerRepo();
var id = await repo.getCustomer(i);
Console.WriteLine(id);
});
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,这不起作用......我不明白为什么,我认为有一个僵局,但我不确定......
因此,在你的方法结束时,customerTasks包含IEnumerable<Task>的是还没有被列举.Select偶数内的代码都没有运行.
在创建这样的任务时,立即实现序列可能更安全,以降低双重枚举的风险(并偶然创建第二批任务).您可以通过调用ToList序列来完成此操作.
所以:
var customerTasks = ids.Select(async i =>
{
ICustomerRepo repo = new CustomerRepo();
var id = await repo.getCustomer(i); //consider changing to GetCustomerAsync
Console.WriteLine(id);
}).ToList();
Run Code Online (Sandbox Code Playgroud)
现在......如何处理你的任务列表?你需要等待他们全部完成......
你可以这样做Task.WhenAll:
await Task.WhenAll(customerTasks);
Run Code Online (Sandbox Code Playgroud)
你可以通过async在Select语句中实际从委托中返回一个值来更进一步,所以你最终会得到一个IEnumerable<Task<Customer>>.
然后你可以使用不同的重载Task.WhenAll:
IEnumerable<Task<Customer>> customerTasks = ids.Select(async i =>
{
ICustomerRepo repo = new CustomerRepo();
var c = await repo.getCustomer(i); //consider changing to GetCustomerAsync
return c;
}).ToList();
Customer[] customers = await Task.WhenAll(customerTasks); //look... all the customers
Run Code Online (Sandbox Code Playgroud)
当然,可能有更有效的方法可以一次性获得几个客户,但这可能是一个不同的问题.
相反,如果您希望按顺序执行异步任务:
var customerTasks = ids.Select(async i =>
{
ICustomerRepo repo = new CustomerRepo();
var id = await repo.getCustomer(i); //consider changing to GetCustomerAsync
Console.WriteLine(id);
});
foreach(var task in customerTasks) //items in sequence will be materialized one-by-one
{
await task;
}
Run Code Online (Sandbox Code Playgroud)