Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在几乎相同的方法中异步/等待的不同行为_C#_.net_Async Await - Fatal编程技术网

C# 在几乎相同的方法中异步/等待的不同行为

C# 在几乎相同的方法中异步/等待的不同行为,c#,.net,async-await,C#,.net,Async Await,假设我有两个异步方法 public async static Task RunAsync1() { await Task.Delay(2000); await Task.Delay(2000); } 及 然后我就这样用它 public static void M() { RunAsync1().GetAwaiter().GetResult(); RunAsync2().GetAwaiter().GetResult(); } 因此,RunAsync1将运行4秒,

假设我有两个异步方法

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

然后我就这样用它

public static void M()
{
    RunAsync1().GetAwaiter().GetResult();
    RunAsync2().GetAwaiter().GetResult();
}
因此,
RunAsync1
将运行4秒,但
RunAsync2
仅运行2秒

有人能解释为什么吗?方法几乎相同。有什么区别

在第二种方法中,两个任务同时启动。它们将在2秒钟内完成(因为它们并行运行)。在第一个方法中,首先运行一个方法(2秒),等待它完成,然后启动第二个方法(2秒)。这里的关键点是任务。延迟(…)在你调用它的时候开始,而不是在你等待它的时候

要进一步澄清,第一种方法:

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
第二种方法:

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

在第一种情况下,你是说

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

  • 0:00在2秒内创建回调0:00
  • 0:00等待回调返回0:02
  • 0:02在2秒内创建回调0:02
  • 0:02等待回调返回0:04
  • 0:04返回 第二个案例是

    public async static Task RunAsync2()
    {
        var t1 = Task.Delay(2000);
        var t2 = Task.Delay(2000);
    
        await t1;
        await t2;
    }
    
  • 0:00在2秒内创建回调0:00
  • 0:00在2秒内创建回调0:00
  • 0:00等待第一次回调0:02
  • 0:02等待第二次回调0:02
  • 0:02返回

  • 换句话说,在第一种方法中,您正在进行顺序异步编程,第二种方法是并行异步编程。

    无论何时启动任务。它已经在您创建它时启动,而不是在您调用
    wait
    时启动


    如果您创建了一个任务并将其放入一个变量中,那么当您等待它时,它可能已经完成了。你的第二个病例就是这样的<代码>等待只需确保它必须在继续之前完成。

    只需检查您的代码:

    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
    }
    
    因此,第二个
    等待任务延迟(2000)在第一次调用完成后调用(2秒后)

    而第二种方法,

    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
    }
    
    因此任务t1和t2同时运行

    如果你把它改成

    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
    }
    

    您将获得与RunAsync1相同的结果。

    这不是变量的问题,而是何时何地使用
    wait
    。如果你做了
    var t1=Task.Delay(2000)然后<代码>等待t1,你会得到相同的结果。第二个4。是否
    0:00等待第二次回调0:02
    ?@camden_kid:不,因为在第三步之后,您已经在0:02了(您已经在那里等待了2秒钟)。@hoffmale它的编写方式有点混乱。在0.02时,它并没有真正等待,因为它刚刚完成等待。@camden_kid:在步骤3中,您将等待任务1完成。这意味着要等到0:02,也就是任务1完成的时候。在步骤4中,您将等待任务2完成。碰巧,任务2正是在那个时刻完成的,所以没有太多的延迟。“等待任务完成”可能意味着“如果任务已经完成,立即返回”。@hoffmale很公平。谢谢。这是面试问题吗?这是演示异步代码如何工作的典型示例…@BlueRaja DannyPflughoeft不,它不是。它只是在存储库中使用的out代码的简单版本。你能告诉我你在哪里看到这段代码的演示吗?@MegaTron关于基本
    async
    行为的讨论。
    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
    }