2

Does this code make sense?

async Task DoSomething() {
     await service.doSomething();
}

Is it just similar in this?

Task DoSomething() {
    return service.doSomething();
}   

OR is it just the same to this?

 void DoSomething() {
    service.doSomething().Wait();
}   

Which code is the best on this scenario?

Linc Abela
  • 797
  • 2
  • 12
  • 26

1 Answers1

4

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.
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
  • But the first example is not necessarily wrong right? it is just ineficient? – Linc Abela Dec 17 '14 at 01:20
  • 2
    Correct. It is only somewhat inefficient. In most scenarios you should probably ignore performance implications here and go for what you think is most readable. – Kirk Woll Dec 17 '14 at 01:21
  • 2
    I think it's also appropriate to point out the fact that when `SynchronizationContext.Current` is not `null`, the first code snippet (with `await` but no `ConfigureAwait(false)`) introduces the possibility of a deadlock (if the caller blocks on the returned `Task`'s completion) where there was potentially none before. That alone is a good enough reason to stay away from `async/await` where it otherwise adds no value. – Kirill Shlenskiy Dec 17 '14 at 01:21
  • @KirillShlenskiy, I never thought of that. That's a great point. – Kirk Woll Dec 17 '14 at 01:25