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

为何使用await运算符时异步方法仍同步执行?

问题原因分析
  • async方法在遇到第一个未完成的await之前,所有代码都是同步在调用线程上执行的:你当前代码里DoAsync的a部分for循环、输出"I'm here B",甚至ReturnsString里输出"I'm here D"的逻辑,都在第一个await(也就是await Task.Delay(2000))之前,所以全部会同步阻塞执行,不会提前释放线程,自然就出现了全同步执行的效果。
  • 调用DoAsync的方式不符合异步规范:Main方法里直接写Console.WriteLine(exe3.DoAsync())没有等待任务完成,只会输出Task对象本身的类型信息,不会等后续异步逻辑执行完毕。
符合预期的修改方案

如果你想让a部分的逻辑和ReturnsString的异步逻辑并行执行,只需要调整代码顺序,先启动异步任务,再执行a部分逻辑,最后等待任务完成即可,修改后代码如下:

public class AsyncAwaitExe3
{
    public async Task<string> DoAsync()
    {
        string toReturn = "";
        Console.WriteLine("I'm here A");
        
        // 先启动异步任务,不立刻await,此时任务会在后台开始执行
        var returnsTask = ReturnsString();

        //a 此时执行for循环的同时,ReturnsString里的Task.Delay也在并行运行
        for (int i = 0; i < 30; i++)
        {
            Console.WriteLine($"inside for {i}");
            // 如果要模拟非阻塞等待可以换成await Task.Delay(1000),对应将循环也放在异步上下文即可
            Thread.Sleep(1000);
        }
        //b
        Console.WriteLine("I'm here B");
        
        // 此时再等待异步任务完成
        toReturn = await returnsTask;

        //c
        Console.WriteLine("I'm here C");
        return toReturn;
    }

    public async Task<string> ReturnsString()
    {
        Console.WriteLine("I'm here D");
        await Task.Delay(2000);
        Console.WriteLine("I'm here E");
        return "sharp sword";
    }
}

static void Main(string[] args)
{
    AsyncAwaitExe3 exe3 = new AsyncAwaitExe3();
    // 等待异步任务执行完成后再输出结果,兼容所有.NET版本
    var result = exe3.DoAsync().GetAwaiter().GetResult();
    Console.WriteLine(result);

    Console.ReadKey();
}

如果你的项目是.NET Core 3.0+或者.NET 5+,可以直接把Main方法声明为async Task Main,直接用await等待DoAsync即可,写法更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:39:03