locked
How to make action Asynchronous in mvc 5 RRS feed

  • Question

  • User-454825017 posted

    see a sample below code. here is no await. so tell me does the below code will be async if i my action signature would be async Task<ActionResult> ?

    if my below code will not be async then tell me how to design my below code which will be purely async....what line i need to add there?

    please guide me with idea how to make any action Asynchronous ?

    public async Task<ActionResult> GizmosAsync()
    {
                Registration reg = new Registration();
                reg.Broker = GetBrokers();
    
                BrokersMain _bm = new BrokersMain();
                _bm.IsDemo = IsDemo;
                //int xx = reg.Broker.Where(a => a.Status == false).ToList().Count;
    
                _bm.SelectAll = (reg.Broker.Count == reg.Broker.Where(a => a.Status == false).ToList().Count ? true : false);
                _bm.ListOfBrokers = reg.Broker;
                _bm.HasData = (_bm.ListOfBrokers.Count > 0 ? true : false);
                TempData.Keep();
    
                return View(_bm);
    }

    i can write the above code this way to use await for async....but tell me this approach will be right or not?

    public async Task<ActionResult> GizmosAsync()
    {
    	await Task.Run(() =>
    	{
    		Registration reg = new Registration();
    		reg.Broker = GetBrokers();
    
    		BrokersMain _bm = new BrokersMain();
    		_bm.IsDemo = IsDemo;
    		//int xx = reg.Broker.Where(a => a.Status == false).ToList().Count;
    
    		_bm.SelectAll = (reg.Broker.Count == reg.Broker.Where(a => a.Status == false).ToList().Count ? true : false);
    		_bm.ListOfBrokers = reg.Broker;
    		_bm.HasData = (_bm.ListOfBrokers.Count > 0 ? true : false);
    		TempData.Keep();
    
    	});
    	return View(_bm);			
    }

    if my question not clear let me know i will explain it in more detail that what i want to know.

    please guide me. thanks

    Thursday, July 9, 2020 7:41 AM

Answers

  • User753101303 posted

    Nope. The purpose of async is to allow the use of await. Please see references to understand how it works. In short the general idea is to have something such as :

    public async Task<ActionResult> GizmosAsync()
    {
       Registration reg = new Registration();
       reg.Broker = await GetDataAsync(); // may take few time to fetch data from db
       return View(reg);
    }
    
    public async Task<IEnumerable<Broker>> GetXXAsync()
    {
       // whatever you need etc...
       result= await <YourLinkQuery>.ToListAsync();
       // whatever you need
       return result;
    }

    With async the C# compiler knows the method should be written in a special way. And then you HAVE to use await to really take advantage of it. What happens basically is :
    - ToListAsync sends the SQL statement and will "return" to make the current thread available for something else. Then a low level mechanism is triggered when the network IO operation is completed and your method is called again to resume where it left (based on hidden data).

    await still skips all this is if the task is already completed.

    Then if you have multiple independant queries, it can be pushed further by starting them all (ie assign the xxAsync result to a task) and then await on all those tasks so that they can run in parallel.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 9, 2020 4:07 PM
  • User475983607 posted

    Sir please guide me how should i compose my action which will take more request. one sample code posting here.

    public async Task<ActionResult> GizmosAsync()
    {
                Registration reg = new Registration();
                reg.Broker = GetBrokers(); // may take few time to fetch data from db
    
                return View(reg);
    }

    in the above code there is no await. so the above code will be synchronous or asynchronous because i used async Task<ActionResult> in method signature ?

    guide how to write action code which can handle maximum request. please take my code and re-post it here which guide me the best way to compose action which can take maximum request.

    if you are writing this action GizmosAsync() then how do you code for best approach ? i am looking for best approach. thanks

    You misunderstand asynchronous programming fundamentals which is causing you to make assumptions.  The thread that executes the GizmosAsync() is an asynchronous thread spun up due to an HTTP request.  The GizmosAsync() method body does not contain an asynchronous method.  There is nothing to execute asynchronously.  

    Perhaps look into making GetBroker() an async method.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 9, 2020 4:09 PM

All replies

  • User-821857111 posted

    Yes, if you want the code to run on a separate thread, using await Task.Run will accomplish that: https://www.pluralsight.com/guides/using-task-run-async-await

    However, if the code in the body of the GizmosAsync method is not long running, there is no benefit to having it running asynchronously anyway.

    Thursday, July 9, 2020 9:39 AM
  • User-454825017 posted

    Sir @Mike i never use Async keyword with action result. so if i compose my code this below way....is it will be asyn because there is no await keyword in the below code. so how it will be async without await ?

    below action will be treated as sync though async is used in method signature ? at all below code approach will be benefited ?

    the main advantage of Asyn Task<ActionResult> is that maximum request can be handle but if we do not use await keyword inside action then how my action can handle multiple request say 1000 request comes with in few second. please help me to design my action which can handle huge request per second.

    i know in real life people use very high end multiple server and load balancer.  apart from hardware issue i like to know how should i design my action in such a way as a result it should be able to handle huge request and after that if we get good hardware then it will perform well. so from developer end i want to know how we should develop a web application with mvc 5 which will be able to handle large request. thanks

    public async Task<ActionResult> GizmosAsync()
    {
                Registration reg = new Registration();
                reg.Broker = GetBrokers();
    
                BrokersMain _bm = new BrokersMain();
                _bm.IsDemo = IsDemo;
                //int xx = reg.Broker.Where(a => a.Status == false).ToList().Count;
    
                _bm.SelectAll = (reg.Broker.Count == reg.Broker.Where(a => a.Status == false).ToList().Count ? true : false);
                _bm.ListOfBrokers = reg.Broker;
                _bm.HasData = (_bm.ListOfBrokers.Count > 0 ? true : false);
                TempData.Keep();
    
                return View(_bm);
    }

    Thursday, July 9, 2020 10:30 AM
  • User753101303 posted

    Hi,

    This is rather the other way round ie IF you end up in having to call async methods such as https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.queryableextensions.tolistasync?view=entity-framework-6.2.0 or maybe CountAsync (GetBrokers is loading the same data as well ?) then you have to change your action to an async action (whose purpose is to support the use of https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/await).

    IMO don't decide to have an async method and then wondering how to make an async call inside. In particular running explicitely a new thread likely won't bring the same scalability benefit. My understanding is that await allows to wait for I/O operation using an efficient dedicated mechanism which precisely allow to avoid using threads for doing that...

    Also once again check your logic but I suspect your retrieve the same data twice. If you need a count you could CountAsync to retrieve the count without loading entities client side and then only counting them.

    Edit: in short, see first which avalaible xxxAsync methods you could use and if you find at least one then turn your action into an async method.

    Thursday, July 9, 2020 11:35 AM
  • User475983607 posted

    TDP

    i never use Async keyword with action result. so if i compose my code this below way....is it will be asyn because there is no await keyword in the below code. so how it will be async without await ?

    There's nothing to await within the method body so the main thread will run synchronously (one line at a time) through the method body.  The Visual Studio compiler warning, green squiggling line, you are see under the method states the same.

    The async/await documentation explains asynchronous quite well using a cooking breakfast analogy.  

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

    TDP

    i know in real life people use very high end multiple server and load balancer.  apart from hardware issue i like to know how should i design my action in such a way as a result it should be able to handle huge request and after that if we get good hardware then it will perform well. so from developer end i want to know how we should develop a web application with mvc 5 which will be able to handle large request. thanks

    It is important to understand, asynchronous programming has been around a long long time.  The newer async/await pattern simply makes coding asynchronous methods easier.  Ultimately, asynchronous methods allow a single system to handle more requests so you can get the most from your servers.  The async/await pattern does not make code run faster and does not stop developers from writing poorly performing code.  For example, your second code snippet with the task.run wastes a thread resource.

    Thursday, July 9, 2020 11:42 AM
  • User-454825017 posted

    Sir please guide me how should i compose my action which will take more request. one sample code posting here.

    public async Task<ActionResult> GizmosAsync()
    {
                Registration reg = new Registration();
                reg.Broker = GetBrokers(); // may take few time to fetch data from db
    
                return View(reg);
    }

    in the above code there is no await. so the above code will be synchronous or asynchronous because i used async Task<ActionResult> in method signature ?

    guide how to write action code which can handle maximum request. please take my code and re-post it here which guide me the best way to compose action which can take maximum request.

    if you are writing this action GizmosAsync() then how do you code for best approach ? i am looking for best approach. thanks

    Thursday, July 9, 2020 3:28 PM
  • User753101303 posted

    Nope. The purpose of async is to allow the use of await. Please see references to understand how it works. In short the general idea is to have something such as :

    public async Task<ActionResult> GizmosAsync()
    {
       Registration reg = new Registration();
       reg.Broker = await GetDataAsync(); // may take few time to fetch data from db
       return View(reg);
    }
    
    public async Task<IEnumerable<Broker>> GetXXAsync()
    {
       // whatever you need etc...
       result= await <YourLinkQuery>.ToListAsync();
       // whatever you need
       return result;
    }

    With async the C# compiler knows the method should be written in a special way. And then you HAVE to use await to really take advantage of it. What happens basically is :
    - ToListAsync sends the SQL statement and will "return" to make the current thread available for something else. Then a low level mechanism is triggered when the network IO operation is completed and your method is called again to resume where it left (based on hidden data).

    await still skips all this is if the task is already completed.

    Then if you have multiple independant queries, it can be pushed further by starting them all (ie assign the xxAsync result to a task) and then await on all those tasks so that they can run in parallel.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 9, 2020 4:07 PM
  • User475983607 posted

    Sir please guide me how should i compose my action which will take more request. one sample code posting here.

    public async Task<ActionResult> GizmosAsync()
    {
                Registration reg = new Registration();
                reg.Broker = GetBrokers(); // may take few time to fetch data from db
    
                return View(reg);
    }

    in the above code there is no await. so the above code will be synchronous or asynchronous because i used async Task<ActionResult> in method signature ?

    guide how to write action code which can handle maximum request. please take my code and re-post it here which guide me the best way to compose action which can take maximum request.

    if you are writing this action GizmosAsync() then how do you code for best approach ? i am looking for best approach. thanks

    You misunderstand asynchronous programming fundamentals which is causing you to make assumptions.  The thread that executes the GizmosAsync() is an asynchronous thread spun up due to an HTTP request.  The GizmosAsync() method body does not contain an asynchronous method.  There is nothing to execute asynchronously.  

    Perhaps look into making GetBroker() an async method.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, July 9, 2020 4:09 PM
  • User-454825017 posted

    I think  ToListAsync() not available in asp.net mvc 5. it is feature of .net core i assume.

    thanks

    Thursday, July 9, 2020 4:31 PM
  • User475983607 posted

    Your response has nothing to do with the subject.  ToListAsync() is available in EF version 4 to 6

    https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.queryableextensions.tolistasync?view=entity-framework-6.2.0

    Thursday, July 9, 2020 4:46 PM
  • User753101303 posted

    No it is part of "Entity Framework" and though I don't remember when it was introduced you have this both in EF 6.x and EF Core. Check which EF version you are using. Either you don't have the proper namespace or you are using an old version not having that yet.

    Thursday, July 9, 2020 6:02 PM