【发布时间】:2016-11-12 14:34:24
【问题描述】:
我的环境是 ASP.NET Core 和 EF Core。我需要在请求期间异步“分页”实体集合。
所以我创建了这个集合类:
public class PagedList<T> : IEnumerable<T> { /* ... */ }
还有这个异步枚举的扩展方法:
public static async Task<PagedList<T>> ToPagedListAsync<T>(this IQueryable<T> items, int pageSize, int pageNumber) {
return await Task.Run(() => new PagedList<T>(items, pageSize, pageNumber));
}
现在我可以这样做了:
var stuff = await repository.CreateQueryableForLoadingStuff().ToPagedListAsync(10, 1);
我查看了source for EF's ToListAsync() 以获得指导——它不只是像我所做的那样包装同步操作,而是直接异步枚举到一个新集合中。 I also saw this 解释了 FooAsync() 方法如果使用 Task.Run() 启动一个新线程就不是“真正的”异步,并且由于我在 ASP.NET 请求中操作,这可能是错误的方法。
我的方法是否适合我的环境(ASP.NET Core 和 EF Core),还是应该使用该链接中的方法?另外,我应该使用.ConfigureAwait(false)吗?
【问题讨论】:
-
这对于 ASP.NET 来说是一种糟糕的技术。您所做的只是创建一个线程。每个 ASP.NET 请求都已在线程池线程上发生。为什么要创建一个额外的线程?此外,从您的示例中很难看出,但看起来您几乎打算在 C# 中进行分页?为什么不让数据库来做呢?这将大大提高效率。如果你只想要 10 行,不要全部返回 10000 然后选择前 10 行,只需使用
Skip和Take来获取你需要的结果。 -
@dman2306
PagedList类使用 EF 的Skip和Take对数据库进行分页。这是我关心的异步枚举。那么,如果它对 ASP.NET 不利,我应该怎么做呢? -
你想做一些像 EF 一样的事情。目标是使 I/O 异步。这意味着,当您等待套接字读取数据时,您希望 ASP.NET 请求线程在操作系统等待 IO 时不使用时返回到线程池。
-
@dman2306 请添加第二条评论作为答案,以便我接受。
标签: c# asp.net entity-framework linq async-await