0

Is there any benefit executing a function using async Task await over executing in the current thread?

[HttpGet]
[Route("example/{id}")]
public async Task<Example> GetExample(int id)
{
    return await exampleService.GetExampleAsync(id);
}

Compared to:

[HttpGet]
[Route("example/{id}")]
public Example GetExample(int id)
{
    return exampleService.GetExampleAsync(id).Result;
}
cfsko
  • 17
  • 5
  • 2
    Yes, avoiding deadlocks. There's almost no reason to ever call `.Result` directly, unless you're writing your own task managing library. In which case you'll want to *really* understand task management. – David Jun 25 '18 at 22:43
  • 1
    Reference [Async/Await - Best Practices in Asynchronous Programming](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx) – Nkosi Jun 25 '18 at 22:53
  • Yes, the call without await is going to block your execution until the method all finishes. This is bad, it slows the server down. When you'll use await keyword, the .Net framework is going to let things run so that the next request can be processed. It will return the response to the caller as soon as the processing will finish. Besides, async/await is new agey man! thin I hope this helps. – Naeem A. Malik Jun 25 '18 at 22:57
  • Let's say GetExampleAsync always takes 2 seconds to execute. My understanding is both GetExample methods will return after 2 seconds. Are you saying concurrent requests to the second GetExample method will be queued up sequentially, whereas concurrent requests to the first GetExample will be executed in parallel? That doesn't make any sense. – cfsko Jun 26 '18 at 00:44
  • Possible duplicate of [What is the advantage of using async with MVC5?](https://stackoverflow.com/questions/19087513/what-is-the-advantage-of-using-async-with-mvc5) – ChiefTwoPencils Jun 26 '18 at 03:31
  • 3
    @David in .NET Core, you can use `.Result` without deadlocks. – Fabio Jun 26 '18 at 04:58
  • 2
    @NaeemA.Malik, OP's methods are controller action, which even with `await` will be blocked until asynchronous method completes. `await` should be used for sake of scalability – Fabio Jun 26 '18 at 05:00
  • @Fabio you can use result without deadlock, is that because there is no UI thread? Do you have a resource on this? – johnny 5 Jun 26 '18 at 20:51
  • @johnny5, because ASP.NET Core doesn't have SynchronizationContext, [ASP.NET Core SynchronizationContext](https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html). It very easy to try ;) – Fabio Jun 26 '18 at 21:29
  • @Fabio why thank you, you've save me the trouble of calling `ConfigureAwait(false)` every where – johnny 5 Jun 26 '18 at 21:33

2 Answers2

0

Yes, the call without await is going to block your execution until the method all finishes.

This is bad, it slows the server down. When you'll use await keyword, the .Net framework is going to let things run so that the next request can be processed.

It will return the response to the caller as soon as the processing will finish. Besides, async/await is new agey man! thin I hope this helps

Naeem A. Malik
  • 995
  • 4
  • 19
  • Isn't that what await GetExampleAsync is doing too? – cfsko Jun 26 '18 at 00:46
  • No, when GetExampleAsync will be called the .Net framework will automatically call it in a multi-threaded asynchronous fashion. Your program will be free to do whatever it wants while the network I/O will wait. As soon as the network I/O will be completed, the execution will resume from the point where await was placed. – Naeem A. Malik Jun 26 '18 at 10:15
  • 1
    @NaeemA.Malik You have no idea what `GetExampleAsync` and whether or not it uses multiple threads. It's likely that it doesn't (it certainly shouldn't' in a context like this). It's asynchronous, not multithreaded. There's a big difference between the two. – Servy Jun 26 '18 at 19:40
  • Okay, maybe I'm missing something. – Naeem A. Malik Jun 28 '18 at 12:59
0

The primary difference between your two samples is that the second is synchronous and blocking. There's no good reason to block on async code, as has been covered many other places. Your first example however needlessly generates a state machine to handle the unnecessary async pieces. If you have nothing to do after an await within an async method simply return the Task:

[HttpGet]
[Route("example/{id}")]
public Task<Example> GetExample(int id)
{
    return exampleService.GetExampleAsync(id);
}
JSteward
  • 6,833
  • 2
  • 21
  • 30