Если вы хотите внедрить асинхронный метод в глубине иерархии вызовов, является ли наилучшей практикой (или наилучшей рекомендуемой практикой), чтобы сделать всех родителей асинхронными?
Я полностью понимаю, как поток управления движется в асинхронных методах, но большинство примеров в Интернете показывают только один метод. Меня интересует, как работать с async / await в глубоко вложенной иерархии вызовов.
Например, что произойдет, если у вас есть:
void ControllerMethod() // Root method
{
ServiceA_MethodOne();
}
// In another place in code
void ServiceA_MethodOne()
{
ServiceB_MethodOne();
}
// In another place in code
async Task<List<Product>> ServiceB_MethodOne()
{
var data = await ctx.Products.ToListAsync();
// some code here works with data.
}
Похоже, что по сути, потому что вы хотели получать Products асинхронно в одном из ваших глубоко вложенных дочерних методов, все родительские методы теперь должны быть помечены как асинхронные (я специально не пометил родителей как асинхронных в приведенном выше примере) пример)
Это правильное предположение?
Теперь я знаю о GetAwaiter().GetResult()
, который фактически может сделать это:
void ControllerMethod() // Root method
{
ServiceA_MethodOne();
}
// In another place in code
void ServiceA_MethodOne()
{
ServiceB_MethodOne().GetAwaiter().GetResult();
}
// In another place in code
async Task<List<Product>> ServiceB_MethodOne()
{
var data = await ctx.Products.ToListAsync();
// some code here works with data.
}
Это был бы один из способов "инкапсулировать" асинхронность в один метод. Но во многих статьях / руководствах это нахмурилось (и за этим стоят действительные, но еще не понятые технические объяснения)
Итак, чтобы подвести итог вопроса в более общем виде: когда вы используете async / await для метода, вся ли иерархия ваших родительских вызовов, начиная с прямого родителя, который вызывает ваш метод, полностью переходит к корневому методу (вызывающему которого вы не иметь контроля над), быть реализованы как асинхронные методы?