异步/等待多个CountAsync数据库调用EFCore

时间:2019-07-26 17:02:52

标签: c# asp.net-core async-await entity-framework-core entity-framework-core-2.2

我正在尝试确保我了解异步/等待。在下面的示例中,我的代码将异步还是同步运行?

我的理解(可能是错误的)是,每个异步数据库调用都不必等待上一个调用完成。因此,我基本上可以运行多个CountAsync调用,并且它们都将同时运行,直到此时某些事情试图从一个异步调用中获取数据。

这是我当前拥有的:(所有的select / where逻辑都已删除,因为这个问题不需要使用)

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;
    }

我的同事说这是不正确的,所有呼叫将同步运行;因此,我问这个问题的原因。如果我错了,那么编写此方法的正确方法是什么,以便所有异步调用同时运行?

1 个答案:

答案 0 :(得分:1)

任务热返回或已启动。 await关键字的字面意思是从此处停止直到任务完成。因此,是的,有了您的代码,每个查询将在您继续进行时依次依次运行,每次一次,然后在每一行停止。

要并行运行,只需要启动任务即可。例如:

var totalCustomersTask = _context.Customers.CountAsync(x => [...]);

var myTotalCustomersTask = _context.Customers.CountAsync(x => [...]);
var myClosedCustomers = _context.Customers.CountAsync(x => [...]);
var myNotStartedCustomers = _context.Customers.CountAsync(x => [...]);

...

请注意,所有这些行中都没有await。然后,在完成所有任务之后:

model.TotalCustomers = await totalCustomersTask;

model.MyTotalCustomers = await myTotalCustomersTask;
model.MyClosedCustomers = await myClosedCustomersTask;
model.MyNotStartedCustomers = await myNotStartedCustomers;

...

尽管异步操作可以并行运行,但异步与“并行”不同。