In my ASP.NET Core API, I need to make 3 separate calls to 3 different repositories in order to collect all the data I need to make decisions.
I want to shave off all the time I can in order to speed things up. Is there any difference in terms of time it will take for all 3 call to complete using the regular or a parallel invoke approach?
The regular way would be:
var customer = await _customersRepository.GetCustomer(customerId);
var balance = await _salesRepository.GetCustomerBalance(customerId);
var product = await _productsRepository.GetProduct(productId);
I haven't used the parallel approach before but I think it goes something like this:
Customer customer;
Balance balance;
Product product;
Parallel.Invoke(
() =>
{
customer = await _customerRepository.GetCustomer(customerId);
},
() =>
{
balance = await _salesRepository.GetCustomerBalance(customerId);
},
() =>
{
product = await _productRepository.GetProduct(productid);
});
Again, my main concern is to complete all three repository/database calls as quickly as I can so that I have all the data I need to make a decision. With that said:
- Is there any benefit to running parallel tasks to save time?
- Are there any other benefits or concerns to using the parallel invoke approach?
CodePudding user response:
Depending on the time that the repository actions take it can be beneficial to execute them in parallel. However the DbContext is not thread-safe so be sure to retrieve a separate instance for each execution (assuming they read from a DbContext). Also take a look at this thread for more information regarding parallel execution with EF Core: What is the best practice in EF Core for using parallel async calls with an Injected DbContext?
CodePudding user response:
It's far better if you can construct a single query to the database retrieving all your data at once.
But if you must do multiple concurrent database calls, you can do so using Task.WhenAll
(note: not Parallel
). You would have to ensure that your repositories use different database contexts, since EF contexts do not support concurrency:
var customerTask = _customersRepository.GetCustomer(customerId);
var balanceTask = _salesRepository.GetCustomerBalance(customerId);
var productTask = _productsRepository.GetProduct(productId);
await Task.WhenAll(customerTask, balanceTask, productTask);
var customer = await customerTask;
var balance = await balanceTask;
var product = await productTask;