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

C#中Async与Await理解误区:异步函数为何同步阻塞?

异步代码阻塞问题的分析与修正

你的异步选项执行时和同步一样冻结程序,核心是三个关键错误:

错误1:异步方法误用同步阻塞API

startMouseAsync和startFrogAsync里的Thread.Sleep()是同步阻塞线程的操作,哪怕方法标记了async,这个调用会直接卡死当前线程,完全无法发挥异步的非阻塞特性。必须替换为await Task.Delay(),这才是真正的异步等待,会释放当前线程去处理其他逻辑。

错误2:用同步等待替代异步等待

startTaskAsync里的Task.WaitAll()是同步等待所有任务完成,会直接阻塞当前线程直到任务结束。正确做法是用await Task.WhenAll(),这样会异步等待,线程可以被释放去执行你期望的Hello World输出。

错误3:结果获取方式不符合异步规范

你用FrogTask.Result和MouseTask.Result获取结果,在同步场景下没问题,但异步场景下应该用await获取,避免额外的线程阻塞。


修正后的完整代码

await Main();

static async Task Main()
{
    string input = "start";
    while (input != "exit")
    {
        Console.WriteLine("choose an option:");
        Console.WriteLine("1 asynchrone");
        Console.WriteLine("2 synchrone");
        Console.WriteLine("exit.");
        input = Console.ReadLine();
        switch (input)
        {
            case "1":
                // 先启动异步任务,再输出Hello World,最后等待任务完成
                var asyncTask = startTaskAsync();
                Console.WriteLine("Hello World");
                await asyncTask;
                break;
            case "2":
                startTaskSync();
                break;
            case "exit":
                input = "exit";
                break;
            default:
                input = "exit";
                break;
        }
    }
}

static async Task startTaskAsync()
{
    var frogTask = startFrogAsync();
    var mouseTask = startMouseAsync();
    // 异步等待所有任务完成,不阻塞线程
    await Task.WhenAll(frogTask, mouseTask);
    // 用await安全获取异步任务结果
    Console.WriteLine(await frogTask);
    Console.WriteLine(await mouseTask);
}

static void startTaskSync()
{
    string result1 = startFrogSync();
    string result2 = startMouseSync();
    Console.WriteLine(result1);
    Console.WriteLine(result2);
}

static async Task<string> startMouseAsync()
{
    string result = "startMouseAsync completed";
    // 异步等待,释放当前线程
    await Task.Delay(2000);
    return result;
}

static async Task<string> startFrogAsync()
{
    string result = "startFrogAsync completed";
    await Task.Delay(10000);
    return result;
}

static string startMouseSync()
{
    string result = "startMouseSync completed";
    Thread.Sleep(2000);
    return result;
}

static string startFrogSync()
{
    string result = "startFrogSync completed";
    Thread.Sleep(10000);
    return result;
}

修正后的执行效果

选择选项1后:

  1. 立即启动两个异步任务在后台执行
  2. 马上输出Hello World
  3. 主线程异步等待任务完成,10秒后输出两个任务的结果
    整个过程中控制台不会冻结,完全符合你期望的异步非阻塞表现

内容的提问来源于stack exchange,提问作者Z.J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:45:29