Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always use async/await in ASP.NET Core API Controller

As an example I have an ASP.NET Core API controller fetching some data from a service and 2 possible ways to implement the controller method:

With async/await:

[HttpGet]
public async Task<IActionResult> GetSomeDataAsync()
{
   return await someService.GetSomeDataAsync();
}

Without async/await:

[HttpGet]
public Task<IActionResult> GetSomeDataAsync()
{
   return someService.GetSomeDataAsync();
}

Which one of these two is better? The key here is that there is only 1 call to another async method (someService.GetSomeDataAsync()).

like image 712
Eric Avatar asked Apr 11 '20 07:04

Eric


People also ask

Should .NET Core API be async?

ASP.NET Core apps should be designed to process many requests simultaneously. Asynchronous APIs allow a small pool of threads to handle thousands of concurrent requests by not waiting on blocking calls. Rather than waiting on a long-running synchronous task to complete, the thread can work on another request.

Should I always use async await C#?

This is important to keep in mind. If await is not used in the body of an async method, the C# compiler generates a warning, but the code compiles and runs as if it were a normal method. This is incredibly inefficient, as the state machine generated by the C# compiler for the async method is not accomplishing anything.

Should I use async controller actions?

When to use Asynchronous Controller. Asynchronous action methods are useful when an action must perform several independent long running operations. Suppose we have three operations which takes 500, 600 and 700 milliseconds. With the synchronous call, total response time would be slightly more than 1800 milliseconds.

Why we use async and await in ASP.NET Core?

When we don't want to return a result from our async method, we should always return a Task. To validate our asynchronous operations, we have to use the await keyword while calling that operation. When we convert our synchronous code to asynchronous, we have to use the async and await keywords all the way up the chain.


1 Answers

According to ASP.NET Core Performance Best Practices from ASP.NET team:

Avoid blocking calls

ASP.NET Core apps should be designed to process many requests simultaneously. Asynchronous APIs allow a small pool of threads to handle thousands of concurrent requests by not waiting on blocking calls. Rather than waiting on a long-running synchronous task to complete, the thread can work on another request.

A common performance problem in ASP.NET Core apps is blocking calls that could be asynchronous. Many synchronous blocking calls lead to Thread Pool starvation and degraded response times.

  • Make hot code paths asynchronous.
  • Call data access, I/O, and long-running operations APIs asynchronously if an asynchronous API is available. Do not use Task.Run to make a synchronus API asynchronous.
  • Make controller/Razor Page actions asynchronous. The entire call stack is asynchronous in order to benefit from async/await patterns.

Avoid synchronous read or write on HttpRequest/HttpResponse body

All I/O in ASP.NET Core is asynchronous. Servers implement the Stream interface, which has both synchronous and asynchronous overloads. The asynchronous ones should be preferred to avoid blocking thread pool threads. Blocking threads can lead to thread pool starvation.

Prefer ReadFormAsync over Request.Form

Use HttpContext.Request.ReadFormAsync instead of HttpContext.Request.Form. HttpContext.Request.Form can be safely read-only with the following conditions:

  • The form has been read by a call to ReadFormAsync, and
  • The cached form value is being read using HttpContext.Request.Form

Optimize data access and I/O

Interactions with a data store and other remote services are often the slowest parts of an ASP.NET Core app. Reading and writing data efficiently is critical for good performance.

  • Do call all data access APIs asynchronously.
like image 178
Mohsen Esmailpour Avatar answered Sep 22 '22 10:09

Mohsen Esmailpour