If you want to implement an async method deep in your call hierarchy, is the best practice (or the best suggested practice) is to make all the parents async?
I completely understand how the control flow moves in async methods, but most of the examples on the internet show just one method. I am interested in how to work with async/await in a deeply nested call hierarchy.
For example, what happens if you have:
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.
}
It seems that essentially because you wanted to get Products asynchronously in one of your deeply nested children methods, all the parent methods now have to marked as async (I did not mark the parents as async in the above example on purpose for this example)
Is this a correct assumption?
Now, I know about GetAwaiter().GetResult(), which in effect can do this:
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.
}
This would be one way to basically "encapsulate" the async into one method. But in a lot of articles/tutorials this is frowned up (and there are valid but not yet understood technical explanations behind it)
So to summarize the question even more generally: when you use async/await on a method, does your whole parent caller hierarchy, starting from the direct parent that calls your method, all way up to the root method (whose caller you have no control over), be implemented as async methods?