Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a view with async keyword

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.

like image 882
Jalpesh Vadgama Avatar asked Jul 21 '17 01:07

Jalpesh Vadgama


People also ask

Can async method have return value?

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.

What does the async keyword do?

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.

How do I return a view in C#?

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.

What return types are allowed for asynchronous methods?

Async Method Return Types There are three return types that a method marked async may have: void. Task. Task< T > for some type T.


1 Answers

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.

like image 164
Bob Dust Avatar answered Oct 11 '22 14:10

Bob Dust