实际发生一个LINQ语句中使用异步时/等待? [英] What actually happens when using async/await inside a LINQ statement?

查看:101
本文介绍了实际发生一个LINQ语句中使用异步时/等待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码片断编译,但我希望它等待任务的结果,而不是给我一个列表<任务< T>>

The following snippet compiles, but I'd expect it to await the task result instead of giving me a List<Task<T>>.

var foo = bars.Select(async bar => await Baz(bar)).ToList()

随着指出这里,你需要使用 Task.WhenAll

var tasks = foos.Select(async foo => await DoSomethingAsync(foo)).ToList();
await Task.WhenAll(tasks);

但是,<一个href=\"http://stackoverflow.com/questions/21868087/how-to-await-a-list-of-tasks-asynchronously-using-linq#comment33110750_21868161\">a注释指出,异步等待中的选择()不需要

var tasks = foos.Select(foo => DoSomethingAsync(foo)).ToList();

有一个类似的问题<一href=\"http://$c$creview.stackexchange.com/questions/32160/filtering-a-collection-by-an-async-result\">here如果有人试图使用异步方法在其中()

A similar question here where someone tries to use an async method inside a Where().

所以异步等待 A LINQ语句中是合法的语法,但它在所有什么也不做,不它有一定的使用?

So async and await inside a LINQ statement is legal syntax, but does it do nothing at all or does it have a certain use?

推荐答案

我建议你不要认为这是用异步中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.

这篇关于实际发生一个LINQ语句中使用异步时/等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆