Different behavior async/await in almost the same methods

后端 未结 4 1580
粉色の甜心
粉色の甜心 2021-01-17 09:59

Let\'s say I have two async methods

public async static Task RunAsync1()
{
    await Task.Delay(2000);
    await Task.Delay(2000);
}

and

相关标签:
4条回答
  • 2021-01-17 10:23

    Whenever you start a Task. It already started when you created it, not when you called await.

    If you create a task and put it in a variable, it might already finish when you await that. This is what happen to your second case. await just ensures that it must finish before continuing.

    0 讨论(0)
  • 2021-01-17 10:28

    In the second method 2 tasks are started at the same time. They will both finish in 2 seconds (as they are running in parallel). In the first method you first run one method (2 seconds), wait for it to complete, then start the second one (2 more seconds). The key point here is Task.Delay(..) starts right when you call it, not when you await it.

    To clarify more, first method:

    var t1 = Task.Delay(2000); // this task is running now
    await t1; // returns 2 seconds later
    var t2 = Task.Delay(2000); // this task is running now
    await t2; // returns 2 more seconds later
    

    Second method:

    var t1 = Task.Delay(2000); 
    var t2 = Task.Delay(2000); // both are running now
    
    await t1; // returns in about 2 seconds
    await t2; // returns almost immediately, because t2 is already running for 2 seconds
    
    0 讨论(0)
  • 2021-01-17 10:29

    In the first case you are saying

    public async static Task RunAsync1()
    {
        var t1 = Task.Delay(2000);
        await t1;
        var t2 = await Task.Delay(2000);
        await t2;
    }
    

    Which equates to

    1. 0:00 Create a callback in 2 seconds 0:00
    2. 0:00 Wait until the callback has returned 0:02
    3. 0:02 Create a callback in 2 seconds 0:02
    4. 0:02 Wait until the callback has returned 0:04
    5. 0:04 return;

    The second case is

    public async static Task RunAsync2()
    {
        var t1 = Task.Delay(2000);
        var t2 = Task.Delay(2000);
    
        await t1;
        await t2;
    }
    
    1. 0:00 Create callbacks in 2 seconds 0:00
    2. 0:00 Create callbacks in 2 seconds 0:00
    3. 0:00 Wait for first callback 0:02
    4. 0:02 Wait for the second callback 0:02
    5. 0:02 return

    In other words, in the first one you are doing sequential asynchronous programming, and the second is parallel asynchronous programming.

    0 讨论(0)
  • 2021-01-17 10:44

    Just examine your code:

    public async static Task RunAsync1()
    {
        await Task.Delay(2000); // Start a delay task, and WAIT for it to finish
        await Task.Delay(2000); // Start a delay task, and WAIT for it to finish
    }
    

    So the second await Task.Delay(2000); is called after the first call is finished (after 2 seconds).

    While the second method,

    public async static Task RunAsync2()
    {
        var t1 = Task.Delay(2000); // Start a task
        var t2 = Task.Delay(2000); // Start a task
    
        await t1; // Wait for task to finish
        await t2; // Wait for task to finish
    }
    

    So tasks t1, and t2 run at the same time.

    If you change it to

    public async static Task RunAsync3()
    {
        var t1 = Task.Delay(2000); // Start a task
        await t1; // Wait for task to finish
    
        var t2 = Task.Delay(2000); // Start a task
        await t2; // Wait for task to finish
    }
    

    you would get the same results as in RunAsync1.

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