Skip to main content
 首页 » 编程设计

c#之MVC Controller 上的异步等待,带有选择并返回集合的存储库

2024年02月05日29youxin

我有一个 MVC Controller 操作,它列出了给定“应用程序”的所有“功能”,然后将其显示为表格。

我在这里使用异步是否正确?

Controller Action 是异步的,即

public async Task<IActionResult> List(string id) 
{ 
  return View(await new FeatureRepository(_context).GetAllFeatures()); 
} 

和我的功能库(稍后我将通过依赖注入(inject)实例化)...

public class FeatureRepository 
{ 
  private ApplicationDbContext _context; 
 
  public FeatureRepository(ApplicationDbContext context) 
  { 
    _context = context; 
  } 
 
  public async Task<IQueryable<ApplicationFeature>> GetAllFeatures() 
  { 
    var query = from d in _context.ApplicationFeatures 
                select d; 
 
    return query; 
   } 
 
} 

或者我需要使用:

await query.ToListAsync() 

然后返回一个List?尽量避免使用任何类型的 ToList,因为我不想在需要时运行查询,即推迟执行。

它似乎运行良好,但在我重现 X 次之前,我想确保它是以一种仍然不会同步运行的方式完成的。

谢谢! 丹.

(MVC 6、ASP.NET 5、 Entity Framework 7、VS2015)

请您参考如下方法:

您的 await GetAllFeatures 并没有等待任何事情,因为该方法没有执行任何异步操作,只是返回一个 IQueryable。

因此您需要在某处调用 ToListAsync。如果您希望您的存储库返回可查询的,则从那里删除所有异步/等待并在操作中使用 ToListAsync。

顺便说一下,请记住按照 Microsoft 的约定使用 Async 后缀命名异步方法。

只是为了澄清 EF 何时公开异步(因为没有任何意义):

MVC 中异步操作的要点是在有不需要 IIS 处理的操作时释放 IIS 线程。最常见和最明显的情况是数据库操作。 这就是为什么大多数 MVC 异步示例都与 EF 相关的原因,因为您可以让 IIS 处理其他请求,同时 DB 正在处理查询。

也就是说,在谈论 EF 时,只有公开异步的 EF 方法才是执行数据库操作的方法。这就是为什么您没有“AddAsync”(因为 Add 仅适用于 DbContext)而您有“SaveChangesAsync”(因为在这种情况下它实际上执行数据库插入)。

结论:要充分利用异步操作,您应该使用所有可用的 EF 异步方法。如果您的操作不使用任何异步方法,则该操作不应该是异步的。