I recently gave a talk at ThatConference on async
on the server side, and I address this issue in the slides.
On the server side, you want to avoid the use of Task.Run
and other constructs that queue work to the thread pool. As much as possible, keep thread pool threads available for handling requests.
So, ideally your repository would have an asynchronous method GetAllErrorLogsAsync
, which would itself be asynchronous. If GetAllErrorLogs
cannot be asynchronous, then you may as well just call it directly (removing the await Task.Run
).
Since it can take a second to fetch all the error logs I want to have the opportunity to do other stuff once I called the GetAllErrorLogs() method.
If you have a GetAllErrorLogsAsync
available, then this can easily be done using Task.WhenAll
. However, if GetAllErrorLogs
is synchronous, then you can only do this by doing parallel work in your request (e.g., multiple calls to Task.Run
followed by Task.WhenAll
).
Parallel code on the server must be approached with great trepidation. It is only acceptable in a very limited set of scenarios. The entire point of async
on the server side is to use fewer threads per request, and when you start parallelizing, you're doing the opposite: multiple threads per request. This is only appropriate if you know your user base is very small; otherwise, you'll kill your server scalability.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…