在对await
的过度使用情况进行了this article的阅读之后,我决定在可能的地方删除等待。由于两个原因,这导致我的数据服务出现问题:
Task<IEnumerable<T>>
ToEnumerableAsync
。现在,当我删除await
时,编译器将不再展开Task
对象,而我会遇到编译错误,该错误表明Task<List<T>>
无法转换为Task<IEnumerable<T>>
。
因此,我着手创建自己的ToEnumerableAsnyc
。 “ PoC”版本如下所示:
public static IEnumerable<T> ToEnumerableAsync<T>(this IQueryable<T> source)
=> (await source.ToListAsync()).AsEnumerable();
但是,这只会包裹多余的await
而不会将其删除,也就是说,仍然有我的await
和ToListAsync
内部使用的那个。从以上链接的文章来看,这会产生不必要的开销。这不是什么大问题,但仍然是开销。如果我错了,请纠正我:)
因此,我着手查找Microsoft开发人员如何在 ASP.NET Core 2.2 中实现ToListAsync
,并且设法创建了自己的ToEnumerableAsync
实现。根据他们的解决方案不使用await
。看起来就是这样:
public static Task<IEnumerable<T>> ToEnumerableAsync<T>(this IQueryable<T> queryable)
{
var asyncEnum = AsAsyncEnumerable(queryable);
var list = new List<T>();
return asyncEnum.Aggregate(
(IEnumerable<T>)list,
(list, x) =>
{
((List<T>)list).Add(x);
return list;
});
}
private static IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IQueryable<T> queryable)
{
if (queryable is IAsyncEnumerable<T> asyncEnumerable)
{
return asyncEnumerable;
}
throw new InvalidOperationException(
$"Cannot cast \"IQueryable\" to \"IAsyncEnumerable\". Type: \"{typeof(T).FullName}\"");
}
最后是我的问题:开发人员将显露的IQueryable<T>
强制转换为IAsyncEnumerable<T>
到InvalidOperationExeption
会导致什么问题? IQueryable<T>
如何以及为何无法转换为IAsyncEnumerable<T>
?
原始EF文件:QueriableExtensions.cs。