Your initial example:
async Task DoSomething()
{
await service.doSomething();
}
Is a slightly more inefficient version than your first alternative:
Task DoSomething()
{
return service.doSomething();
}
It's more expensive because it has to create the whole state machine related to async code whereas the version shown above does not require that. If you were to use a disassembler such as IlSpy and inspect the compiler generated symbols, you'd see that a special class gets created for your async
version (DoSomething<d__0>
or some such) that would not be created if you did not use async.
On the other hand, your second example -- using .Wait()
-- should be avoided whenever possible. It illustrates two problems:
- Using
.Wait
means you're opting-out of async
, which defeats the whole point. (The "async" code now gets invoked on the calling thread and blocks)
- Using
.Wait
also often leads to thread deadlocks that are best solved by allowing await
semantics to propagate through your code.