The most common issue I see with async programming is that the naive style seen in most samples/docs is strictly slower than standard imperative programming for one user . In other words, it's pure overhead with no benefit at all unless you're at a very large scale and approaching 100% capacity on your hosts. Most documentation -- and most code I've seen in the wild -- reads like this: var foo = await GetFooAsync(...…
The other use-case was to run multi-step operations which involve waiting on UI threads of appplications, which wouldn't have worked with blocking waits (would prevent redraw). For that use-case "speed" also isn't the highest priority.