[英]Where clause in LINQ calling an async method
我在 class 中有一个方法定义为....
public static async Task<int> GetDCountAsync(int dId)
我试图在 LINQ Where 子句中调用此方法....
var excessD= dToConsider
.Where(async x => await myService.GetDCountAsync(x.Id) >= x.Threshold)
.Select(x => x.Id)
.ToArray();
仅供参考:阈值是一个整数。
我收到异步错误....
'async' 匿名 function 的返回类型必须是 'void', 'Task', 'Task', ......
GetDCountAsync 的返回类型是异步任务。 我哪里错了? 提前致谢!
您可以使用System.Linq.Async package 中已有的功能:
int[] excessD = await dToConsider
.ToAsyncEnumerable()
.WhereAwait(async x => await myService.GetDCountAsync(x.Id) >= x.Threshold)
.Select(x => x.Id)
.ToArrayAsync();
WhereAwait
算子的签名:
// Filters the elements of an async-enumerable sequence based on
// an asynchronous predicate.
public static IAsyncEnumerable<TSource> WhereAwait<TSource>(
this IAsyncEnumerable<TSource> source,
Func<TSource, ValueTask<bool>> predicate);
异步方法myService.GetDCountAsync
将一次为一个元素调用和await
,而不是同时为所有元素调用和等待。
因此,您收到的完整错误消息将是:
无法将异步 lambda 表达式转换为委托类型“Func<int, bool>”。 异步 lambda 表达式可能会返回 void、Task 或 Task,它们都不能转换为“Func<int, bool>”。
它实际上告诉你的是 a.Where() LINQ 调用期望接受一个 int,并返回一个 boolean。但是因为你正在尝试进行异步调用,所以它试图返回 Task。
或者换句话说,编译器说“我看到你在这里使用异步方法,我知道异步方法只能返回 void、Task 或 Task,而且我也知道这个 Where 方法需要一个 bool 返回,所以我知道现在这是行不通的”
部分问题是我们实际上并不知道 dToConsider 是什么类型,在某些情况下,它会寻找延迟执行。 在任何情况下,因为您正在为 WHERE 语句执行自定义代码逻辑,所以我们假设这不是 EntityFramework 或需要延迟的东西,并说它只是一个列表。 在这种情况下,只需使用典型的 ForEach 循环来过滤您的列表即可。
var filteredItems = new List<T>();
foreach(var item in dToConsider)
{
if(await myService.GetDCountAsync(x.Id) >= x.Threshold)
filteredItems.Add(item);
}
我确定有人可能会使用 Task.WhenAll 等为您提供一个很好的扩展方法,但这是完成您需要完成的工作的最简单方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.