async/await function comparison

前端 未结 3 1455
南旧
南旧 2021-01-16 11:57

I am trying to understand async/await and I am wondering if both methods work identically.If not can you explain why?

       public async Task          


        
相关标签:
3条回答
  • 2021-01-16 12:15

    Let me point out a few things with your functions:

    public async Task<Client> GetClient()
    {
        return await _clientRepository.GetAll().Where(x => x.Id == 1).FirstOrDefaultAsync();
    }
    

    This first function is a bit wasteful. Neither async nor await are giving you any benefit. Why do I say that? Well let's just quickly recap the usual benefit of await.

    What await allows you to do is to resume execution of the remainder of the method after the awaited task completes. In your case there is no "remainder of the method" since the return await is the last statement of the method.

    Why is this wasteful? Well, by marking your method asyncyou are basically telling the compiler to generate all the machinery (i.e. state machine) to allow you to resume execution within that same method after each await.

    This machinery is useless in your case since there is nothing after the await to resume executing, so you are better off not marking the method async and instead of return await just do a simple return of the task generated by FirstOrDefaultAsync.

    Doing this will still make the function return and behave asynchronous. Keep in mind that async and await aren't actually what make a function execute asynchronously. async/await simply help setup the machinery to provide "bookmarks" into the various await points in your method so that execution can resume there after each awaited task completes.

    Now let's talk about your second function:

      public Task<Client> GetClient2()
      {
         return Task.FromResult(_clientRepository.GetAll().Where(x => x.Id == 1).FirstOrDefault());
      }
    

    This function is not asynchronous at all. It will execute completely synchronous and not yield the thread at all.

    Even if you did this:

      public async Task<Client> GetClient2()
      {
         return await Task.FromResult(_clientRepository.GetAll().Where(x => x.Id == 1).FirstOrDefault());
      }
    

    The function will still be completely synchronous. Remember, async/await are all about setting up machinery and bookmarks but don't actually have any role on whether the code will execute synchronously or asynchronously.

    So why is this blocking? Because FirstOrDefault() does not return a task, so it means it has to return a Client object. This means it can't return anything until it fully completes the execution of the linq chain. Your Task.FromResult is then just taking this value and wrapping it in a pre-completed task.

    So Just to Recap:

    Only use async/await if you need to resume execution somewhere in the middle of your method.

    Example:

    public async Task<boolean> IsIntegerIGetFromRemoteServerPostitiveAsync(){
          int result = await GetSomeIntegerAsync();
          Console.WriteLine('Resuming execution of the method');
          return i>0;
    }
    

    If you find that you have a single await and it is the last line of the method then don't use async/await, just return the task instead of awaiting it. This avoids unnecessary overhead.

    Example:

    public Task<string> GetUserInformationAsync(string username){
        var url = $"http://userinfo.com?username={username}"
        return GetSomeJsonFromHttpServerAsync(url); //Assuming this returns Task<string>
    }
    
    0 讨论(0)
  • 2021-01-16 12:22

    They are not the same, when you add the async keyword you enable the following two capabilities.

    • The marked async method can use Await or await to designate suspension points. The await operator tells the compiler that the async method can't continue past that point until the awaited asynchronous process is complete. In the meantime, control returns to the caller of the async method.

      The suspension of an async method at an await expression doesn't constitute an exit from the method, and finally blocks don’t run.

    • The marked async method can itself be awaited by methods that call it.

    You should read the async/await documentation here: https://msdn.microsoft.com/en-us/library/hh191443.aspx

    0 讨论(0)
  • 2021-01-16 12:31

    First method: async keyword gives compiler signal for generating state machine. Event if you have empty void method marked as async the compiler will generate state machine.

    Second method: You are returning "hot task" - task that is already completed. This method will act like the normal method.

    Btw it is good idea for second scenario to cache such tasks. For example you can create dictionary witch and return cached task. If you do that you won't allocate each time new task on the heap.

    0 讨论(0)
提交回复
热议问题