Reputation: 397
I tried the code below and the index view is not displayed until the long running method has completed. If I don't use async and await it takes the same amount of time too before the index view is displayed. This has now made me to want to find out what benefits are there in using async and await in an ASP.Net MVC Action Controller?
public async Task<IActionResult> Index()
{
var result = await Task.Run(() => TestAsyncAndAwait());
ViewBag.ResultFromAwait = result;
return View();
}
public int TestAsyncAndAwait()
{
System.Threading.Thread.Sleep(1 * 60 * 1000);
return 1;
}
Upvotes: 3
Views: 1768
Reputation: 456342
I tried the code below
First, you don't want to use fake-asynchronous code for testing. Instead, test the difference between a synchronous method and its true asynchronous counterpart:
public IActionResult Synchronous()
{
Thread.Sleep(1 * 60 * 1000);
ViewBag.ResultFromAwait = 1;
return View();
}
public async Task<IActionResult> Asynchronous()
{
await Task.Delay(1 * 60 * 1000);
ViewBag.ResultFromAwait = 1;
return View();
}
the index view is not displayed until the long running method has completed. If I don't use async and await it takes the same amount of time too before the index view is displayed.
HTTP is a request/response protocol. The client sends the request, and some time later the server sends the response. async
doesn't change how the HTTP protocol works.
This has now made me to want to find out what benefits are there in using async and await in an ASP.Net MVC Action Controller?
async
and await
do not yield to the HTTP client (they can't, since they don't change the HTTP protocol). Instead, they yield to the thread pool. This enables your ASP.NET server to handle more simultaneous requests.
Specifically, with the synchronous examples (in both the question and this answer), an ASP.NET thread is blocked doing the Sleep
for the entire minute. However, with the asynchronous example (in this answer), no ASP.NET thread is used to wait for that minute. Instead, async
/await
allows that thread to return to the ASP.NET thread pool, and when that minute is up, a thread from that thread pool is used to set the ViewBag
value and return the View()
. So that's an entire minute of time where the ASP.NET server can handle more requests than it otherwise could because it has an extra thread available.
The fake-asynchronous example in the question does not have that behavior. Instead of asynchronously waiting, it blocks a thread pool thread, so it's both less efficient and less scalable than the synchronous solution. This is one reason why Task.Run
is discouraged on ASP.NET.
For more information, see this article.
Upvotes: 8