Stop waiting asynchronous methods synchronously #21
Description
Synchronously waiting an asynchronous method (i.e using .Result
or .Wait()
) will cause the calling thread to be blocked until the end of the method.
This leads to several issues, such as thread pool starvation or deadlocks (luckily ASP.NET Core doesn't have a synchronization context anymore, so it's not a problem for us).
When an inner method is asynchronous, every method that calls it should be transformed to asynchronous as well, so we can take advantage of it. It may sound strange at first that an implementation detail (such as a call to a persistence layer) drives the contract of the outer layer, but that's how it should be done (also known as "Async all the way").
We should avoid blocking asynchronous code because, as it blocks the calling thread, we will not be able to scale or offload our work.
The Result property and the Wait method, in particular, will also wrap any exception thrown into an AggregateException. So, if we REALLY need to synchronously wait an asynchronous method, we should use task.GetAwaiter().GetResult()
which will correctly re-throw the original exception.
Unfortunately, the Liquid Framework makes heavily use of the Result property without properly await the tasks.
Note that there's nothing wrong about with using the Result property as long as the task has been awaited.