更新时间:2023-11-10 09:02:22
我建议你不要认为这是用异步
中LINQ。记住什么是在两者之间:代表。一些运营商LINQ采取委托和异步
可用于创建异步委托。
I recommend that you not think of this as "using async
within LINQ". Keep in mind what's in-between the two: delegates. Several LINQ operators take delegates, and async
can be used to create an asynchronous delegate.
所以,当你有一个异步方法 BazAsync
返回一个工作
:
So, when you have an asynchronous method BazAsync
that returns a Task
:
Task BazAsync(TBar bar);
那么这个code导致任务序列:
then this code results in a sequence of tasks:
IEnumerable<Task> tasks = bars.Select(bar => BazAsync(bar));
同样,如果您使用异步
和等待
委托中,要创建一个异步委托返回一个工作
:
Similarly, if you use async
and await
within the delegate, you're creating an asynchronous delegate that returns a Task
:
IEnumerable<Task> tasks = bars.Select(async bar => await BazAsync(bar));
这两个LINQ前pressions在功能上等同。有没有重要的区别。
These two LINQ expressions are functionally equivalent. There are no important differences.
就像普通的LINQ前pressions,在的IEnumerable&LT;任务&GT;
是懒惰的评估。只是,异步方法,如 BazAsync
,你通常会做的不的希望意外双重评价或类似的东西。所以,当你的项目到任务序列,它通常是一个好主意,立即具体化的顺序。这就要求 BazAsync
为源序列中的所有元素,开始将所有的任务:
Just like regular LINQ expressions, the IEnumerable<Task>
is lazy-evaluated. Only, with asynchronous methods like BazAsync
, you usually do not want accidental double-evaluation or anything like that. So, when you project to a sequence of tasks, it's usually a good idea to immediately reify the sequence. This calls BazAsync
for all the elements in the source sequence, starting all the tasks going:
Task[] tasks = bars.Select(bar => BazAsync(bar)).ToArray();
当然,所有我们与选择
做的是的启动的异步操作的每一个元素。如果你想等待他们全部完成,然后用 Task.WhenAll
:
Of course, all we've done with Select
is start an asynchronous operation for each element. If you want to wait for them all to complete, then use Task.WhenAll
:
await Task.WhenAll(tasks);
其他大多数LINQ运营商不与异步委托作为清洁工作。 选择
是pretty简单:你刚开始一个异步操作的每一个元素
Most other LINQ operators do not work as cleanly with asynchronous delegates. Select
is pretty straightforward: you're just starting an asynchronous operation for each element.