【发布时间】:2019-07-27 01:21:31
【问题描述】:
我正在努力确保我理解 async/await。在以下示例中,我的代码是异步运行还是同步运行?
我的理解可能是错误的,即每个异步数据库调用都不必等待上一个调用完成。因此,我基本上可以运行大量 CountAsync 调用,它们会同时运行,直到此时某些东西试图从其中一个异步调用中获取数据。
这是我目前拥有的:(所有选择/位置逻辑已被删除,因为这个问题不需要它)
public async Task<DashboardModel> GetDashboard(DashboardInput input)
{
DashboardModel model = new DashboardModel();
model.MyCustomers = await _context.Customers.Where(x => [...]).Select(x => new DashboardCustomerModel()
{
[...]
}).ToListAsync();
model.TotalCustomers = await _context.Customers.CountAsync(x => [...]);
model.MyTotalCustomers = await _context.Customers.CountAsync(x => [...]);
model.MyClosedCustomers = await _context.Customers.CountAsync(x => [...]);
model.MyNotStartedCustomers = await _context.Customers.CountAsync(x => [...]);
model.OtherTotalCustomers = await _context.Customers.CountAsync(x => [...]);
model.OtherClosedCustomers = await _context.Customers.CountAsync(x => [...]);
model.OtherNotStartedCustomers = await _context.Customers.CountAsync(x => [...]);
model.PreparerApprovedCustomers = await _context.Customers.CountAsync(x => [...]);
model.ReviewerApprovedCustomers = await _context.Customers.CountAsync(x => [...]);
model.ApprovedCustomers = await _context.Customers.CountAsync(x => [...]);
return model;
}
我的同事说这是不正确的,所有的调用都会同步运行;因此我问这个问题的原因。如果我错了,那么编写此方法以使所有异步调用同时运行的正确方法是什么?
【问题讨论】:
-
您似乎混淆了“asynchronously”和“并行”。您的查询将一个接一个地异步顺序运行。这就是
await所做的。如果您希望异步任务并行运行,请参阅stackoverflow.com/q/19431494/11683。但是你cannot do that with EF。 -
如果您希望调用并行运行,则将生成的任务收集到一个集合中,然后使用
Task.WhenAll等待它们。 -
@GSerg:您实际上可以使用 EF 做到这一点,但在所有情况下都这样做并不安全。例如,不支持尝试多次异步更新,因此查询只会在命中时命中数据库,并且在某些情况下可能会导致奇怪或不正确的行为。然而,像运行计数这样的事情是 100% 完全可以异步完成的,因为它对数据没有影响。
标签: c# asp.net-core async-await entity-framework-core entity-framework-core-2.2