42 ms·
Something important to note is that code like this: var a = await AlphaAsync(); var b = await BetaAsync(); var g = await GammaAsync(); will be slo
by jiggawatts 3y ago
Something important to note is that code like this:
var a = await AlphaAsync();
var b = await BetaAsync();
var g = await GammaAsync();
will be slower than the equivalent synchronous code. It does the same work, in the same order, and will not run any part in parallel. It can theoretically scale to more concurrent connections and in-flight requests, but I had a tough time achieving a measurable benefit even in benchmark tests.
To get things running in parallel, the tasks have to be started but not immediately awaited:
var ta = AlphaAsync();
var tb = BetaAsync();
var tg = GammaAsync();
...
var a = await ta; var b = await tb; var g = await tg;
I've only ever seen this turn up in real code maybe once or twice. People just don't do it, and the samples and documentation doesn't show this pattern either.
- Atotalnoob 3y agoAt that point, isn’t Task.WhenAll() better?
- jiggawatts 3y agoOnly if the return types are identical.
- petrzjunior 3y agoIf the async methods return quickly, then yes, there is some overhead. But the point of asynchonous methods is that they can perform slow operations while yielding the calling thread back to the thread pool. For example Alpha might be reading a gigabyte file, Beta is sending it over the network and Gamma waiting for a timer tomorrow. Async/await is a syntactic sugar to run this in a pleasant way.
- jiggawatts 3y agoHere’s the rub: that time will have to be spent no matter what. Async just “frees up the thread”, but the system as a whole will still have to do the same processing. Async doesn’t make a gigabyte sized I/O take less time or somehow “go away”. In fairly extensive tests I found that it is actually pretty rare for threads to be the limiting resource, so async provided no benefit at all. You pretty much need this specific scenario: - A large auto-scale pool - Tuned well to keep load at 80-90%. - High concurrent connections per instance. - Slow dependencies that return small volumes of data. - A much larger back end than the front end. Think 100 VMs at the front and 10K at the back. Violate any of the above and the benefits seem to evaporate. I’m sure that this scenario is common at FAANG sized orgs, but is extremely rare elsewhere.