5

Hopefully this is a nice and simple answer.

I'm using C# MVC Web API in ASP.NET Core 1. I'm creating web methods and I've seen examples with this of returning data.

Example 1:

public async Task<IActionResult> ExampleCall([FromBody]ExampleObj model)
{
     // Call some lower level function...
     var result = LowerLevelCall(model);
     return result;
}

And seen other examples like this.

Example 2:

public async Task<IActionResult> ExampleCall([FromBody]ExampleObj model)
{
     // Call some lower level function...
     var result = await LowerLevelCall(model);
     return result;
}

Main difference is that Example 2 using the await operator. What's the implications of implementing the await operator? Will this free resources up rather than waiting for code to complete in Example 1?

Thanks in advance for any tips!

d219
  • 2,707
  • 5
  • 31
  • 36
Rob
  • 6,819
  • 17
  • 71
  • 131

3 Answers3

6

In your scenario, the async operator will stop the execution of the method until the result is received from LowerLevelCall. However when the execution of the method is stopped, await waits asynchronously so the thread itself is not blocked. After getting the result from LowerLevelCall the method just resumes executing synchronously.

Example 1 - If LowerLevelCall takes a long time to execute, you thread will be blocked and will just sit there and do nothing until the execution of LowerLevelCall is complete.

Example 2 - If you use await, you won't block the thread since await waits asynchronously. After LowerLevelCall finishes executing the result of the method will be assigned to your result variable.

Intro to Async And Await - This article should help you get started with async and await.

d219
  • 2,707
  • 5
  • 31
  • 36
Kerim Emurla
  • 1,141
  • 8
  • 15
  • Thanks everyone! Those answers all make sense! I've opted for this as my "answer" as its nice and simple and to the point, as well as linking to another useful resource. – Rob Apr 25 '16 at 11:46
4

In the first example if LowerLevelCall(model); takes a long time, your result won't be returned before this method finishes and this will block current thread - you have to wait all this time doing nothing.

In the second example current thread won't be blocked and you can do something other.You will get the result asynchronously when LowerLevelCall(model); finishes.

Roman
  • 11,966
  • 10
  • 38
  • 47
3

the different is that the function with the await is wait to finish first his job before return. Now on web page that I make some test, no one from that two functions blocks the running of code, and they continues to run on a thread.

public async Task<IActionResult> ExampleCall([FromBody]ExampleObj model)
{
     // Call some lower level function...
     // ***Here is not return until this function is finish first.***
     var result = await LowerLevelCall(model);
     return result;
}

Lets look inside.... I make two functions similar to yours

    public static async Task<bool> Task1()
    {
         await Task.Delay(10000);
         return true;
    }

    public static async Task<bool> Task2()
    {
         Task.Delay(10000);
         return true;
    }

The final code on this two is a lot different.

With await

private void MoveNext()
{
    bool flag;
    int num = this.<>1__state;
    try
    {
        TaskAwaiter awaiter;
        if (num != 0)
        {
            awaiter = Task.Delay(0x2710).GetAwaiter();
            if (!awaiter.IsCompleted)
            {
                this.<>1__state = num = 0;
                this.<>u__1 = awaiter;
                cTestClass.<Task1>d__0 stateMachine = this;
                this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, cTestClass.<Task1>d__0>(ref awaiter, ref stateMachine);
                return;
            }
        }
        else
        {
            awaiter = this.<>u__1;
            this.<>u__1 = new TaskAwaiter();
            this.<>1__state = num = -1;
        }
        awaiter.GetResult();
        awaiter = new TaskAwaiter();
        flag = true;
    }
    catch (Exception exception)
    {
        this.<>1__state = -2;
        this.<>t__builder.SetException(exception);
        return;
    }
    this.<>1__state = -2;
    this.<>t__builder.SetResult(flag);
}

with out

// MoveNext is the name of warped function that call the thread.
private void MoveNext()
{
    bool flag;
    int num = this.<>1__state;
    try
    {
        Task.Delay(0x2710);
        flag = true;
    }
    catch (Exception exception)
    {
        this.<>1__state = -2;
        this.<>t__builder.SetException(exception);
        return;
    }
    this.<>1__state = -2;
    this.<>t__builder.SetResult(flag);
}

Some comments

All this inline functionality of asp.net have the purpose to simplify and help for asynchronous do thread work. Have a point on desktop programming that is help to not hold the "draw" message from windows to your program, but on asp.net did not have many effects that are visible, and add a lot of overhead. If you don't know exactly how the multitask will be used it may lead on more delay than help because all are happened on server, not on client that no need this kind of multitask.

Aristos
  • 66,005
  • 16
  • 114
  • 150