There are some code samples where I show some code like below.
public async Task<IActionResult> AddUser(User user)
{
///Logic to add user
return View();
}
Is this a good practice to return a view with async action result method as view result it self-does not support async.
I checked in normal scenarios it works perfectly fine but what are the scenarios where it might fail or create problems.
Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.
The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains. Async functions may also be defined as expressions.
To return a view from the controller action method, we can use View() method by passing respective parameters. return View(“ViewName”) – returns the view name specified in the current view folder (view extension name “. cshtml” is not required.
Async Method Return Types There are three return types that a method marked async may have: void. Task. Task< T > for some type T.
The use of async
and await
is a good practice to make your web application scalable, said MSDN (if I remember correctly :)). Basically, it helps utilizing your thread pool so that 1 thread does not necessarily to be allocated to handle only 1 request. Suppose that you have this action:
public async Task<IActionResult> AddUser(User user)
{
///Logic to add user
return await Task.Run(() => View());
}
it's being said that while waiting for the async method to be completed, the thread will be available to be allocated for another work item (e.g another action marked as async) in the .NET run-time thread-pool global queue. This makes the number of threads can be less than the number of requests need handling.
The async
modifier is marked to tell .NET run-time that this is a work item that can be applied mechanism mentioned above. Without await
something, it doesn't help much (if we don't want to say "nothing") in terms of performance or resource optimization.
For proof of concept, I played with following actions in my HomeController
:
public async Task<ActionResult> FineGrained()
{
return await Task.Run(() => {
return Json(Thread.CurrentThread.ManagedThreadId, JsonRequestBehavior.AllowGet);
});
}
public async Task<ActionResult> CoarseGrained()
{
return await Task.Run(async () => {
await Task.Delay(TimeSpan.FromSeconds(5));
return Json(Thread.CurrentThread.ManagedThreadId, JsonRequestBehavior.AllowGet);
});
}
and this is the jquery script to test the thread utilization:
$.when(
$.getJSON('/Home/FineGrained'),
$.getJSON('/Home/CoarseGrained'),
$.getJSON('/Home/FineGrained'),
$.getJSON('/Home/FineGrained'),
$.getJSON('/Home/FineGrained')
).done(function (v1, v2, v3, v4, v5) {
console.log(v1[0]);
console.log(v2[0]);
console.log(v3[0]);
console.log(v4[0]);
console.log(v5[0]);
});
One of many results I got: 30 25 30 30 25
I refreshed the page containing the test script several times and always got repeat thread id. It's fair enough to prove the theory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With