You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何直接await异步方法同步执行,先声明Task变量则异步执行?

异步任务调用方式的差异解析

我正试图理解异步任务的正确调用方式,请看以下代码:

var stopWatch = new Stopwatch();

// TEST 1 AWAITS THE ASYNC TASKS DIRECTLY
stopWatch.Start();
Console.WriteLine($"Test 1 Begin: {stopWatch.ElapsedMilliseconds}");
await Task1(stopWatch);
await Task2(stopWatch);
Console.WriteLine($"Test 1 End: {stopWatch.ElapsedMilliseconds}");


Console.WriteLine();
Console.WriteLine();
stopWatch.Restart();


// TEST 2 CREATES A LOCAL VARIABLE OF THE TASK THEN AWAITS THE LOCAL VARIABLE
Console.WriteLine($"Test 2 Begin: {stopWatch.ElapsedMilliseconds}");
var task1 = Task1(stopWatch);
var task2 = Task2(stopWatch);
await task1;
await task2;
Console.WriteLine($"Test 2 End: {stopWatch.ElapsedMilliseconds}");


async Task Task1(Stopwatch stopWatch)
{
    Console.WriteLine($"Task 1 Start: {stopWatch.ElapsedMilliseconds}");
    await Task.Delay(2000);
    Console.WriteLine($"Task 1 End: {stopWatch.ElapsedMilliseconds}");
}

async Task Task2(Stopwatch stopWatch)
{
    Console.WriteLine($"Task 2 Start: {stopWatch.ElapsedMilliseconds}");
    await Task.Delay(2000);
    Console.WriteLine($"Task 2 End: {stopWatch.ElapsedMilliseconds}");
}

测试1总耗时:4秒
测试2总耗时:2秒
为何测试1会同步执行,而测试2是异步执行?


核心差异:任务的启动与等待时机

  • 测试1:串行执行
    执行await Task1(stopWatch)时,程序先同步运行Task1的代码,直到遇到await Task.Delay(2000)——此时Task1挂起并返回未完成的任务,主线程开始等待该任务结束(耗时2秒)。只有等Task1完全执行完毕,才会调用Task2(stopWatch),重复相同的等待流程。两个任务是依次启动、依次完成的,总耗时为2秒+2秒=4秒。

  • 测试2:并行执行
    先执行var task1 = Task1(stopWatch),Task1启动后运行到await处挂起,返回未完成的任务;紧接着立刻执行var task2 = Task2(stopWatch),Task2也同步启动并挂起。此时两个任务已同时在后台执行,后续的await task1和await task2只是等待这两个已启动的任务完成。因为任务并行运行,总耗时接近2秒(忽略启动的微小时间差)。

简单总结:测试1是"做完一个再启动下一个",测试2是"先启动所有任务,再一起等结果",这就是两者耗时差异的根本原因。


内容的提问来源于stack exchange,提问作者wamaral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:18:18