尝试await
在查询中使用关键字LINQ
,我得到了这个:
'await' 运算符只能用于初始 'from' 子句的第一个集合表达式中的查询表达式或 'join' 子句的集合表达式中
示例代码:
var data = (from id in ids
let d = await LoadDataAsync(id)
select d);
是否不可能在LINQ
查询中等待某些内容,或者是否需要以不同的方式构造?
尝试await
在查询中使用关键字LINQ
,我得到了这个:
'await' 运算符只能用于初始 'from' 子句的第一个集合表达式中的查询表达式或 'join' 子句的集合表达式中
示例代码:
var data = (from id in ids
let d = await LoadDataAsync(id)
select d);
是否不可能在LINQ
查询中等待某些内容,或者是否需要以不同的方式构造?
LINQ 对async
/的支持非常有限await
。对于 LINQ-to-objects,我所知道的唯一真正有用的操作是Select
使用async
委托(这会导致一系列任务)。
List<T> data = new List<T>();
foreach (var id in ids)
data.Add(await LoadDataAsync(id));
如果您可以LoadDataAsync
安全地并行执行,您的示例可以重写为:
T[] data = await Task.WhenAll(ids.Select(id => LoadDataAsync(id)));
您可以自己定义一些异步 linq 操作(用于 linq to objects):例如:您可以编写自己的 WhereAsync 扩展方法:
public static async Task<IEnumerable<T>> WhereAsync<T>(
this IEnumerable<T> target, Func<T, Task<bool>> predicateAsync)
{
var tasks = target.Select(async x => new { Predicate = await predicateAsync(x).ConfigureAwait(false), Value = x }).ToArray();
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
return results.Where(x => x.Predicate).Select(x => x.Value);
}
并像这样使用它:
var ints = new List<int> { 1, 2, 3 };
var smallInts = await ints.WhereAsync(IsSmallIntAsync);
使用响应式扩展,可以像这样异步处理 linq 查询的结果:
(from d in ids
select LoadDataAsync(d).ToObservable()).Merge()
这为您提供了一个可观察的流,您可以以各种方式响应。例如,您可以将结果缓冲到一个带有超时的列表中。
上面实质上是说“对于 ids 中的每个 d,对其应用一个异步函数,该函数为每个 d 产生一个任务,并将其视为单个结果的 observable (ToObservable),并将所有这些 observable 一起视为单个可观察流(合并)