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

C#测试并行任务却串行执行,问题根源是什么?

异步并行任务执行异常问题解析

问题描述

我查阅了大量关于并行任务运行的问答,编写了一段简单测试代码以验证对异步并行基础原理的理解。代码如下:

public async Task sleeper(int s)
{
    Thread.Sleep(s);
}

public async Task t1()
{
    for (int i=0; i<10; i++)
    {
        Console.WriteLine("T1: " + i);
        await sleeper(5000);
    }
}

public async Task t2()
{
    for (int i=0; i<10; i++)
    {
        Console.WriteLine("T2: " + i);
        await sleeper(3000);
    }
}

public async Task runIt()
{
    var task1 = t1();
    var task2 = t2();
    await Task.WhenAll(task1, task2);
    Console.WriteLine("got it");
}

预期输出为交替执行的结果,例如:

T1: 0
T2: 0
T1: 1
T1: 2
T2: 1
...
但实际得到的却是串行执行的结果:
T1: 0
T1: 1
...
T1: 9
T2: 0
T2: 1
...
想请教问题出在哪里?

问题原因与解决方法

核心问题出在sleeper方法中的Thread.Sleep(s)——这是阻塞当前线程的同步操作,并非真正的异步等待。

执行流程细节:

  • 调用t1()时,代码同步执行到await sleeper(5000),进入sleeper方法后,Thread.Sleep(5000)直接卡住当前线程,5秒内线程无法处理任何其他任务。
  • 5秒后sleeper返回,t1继续下一次循环迭代,再次阻塞线程。
  • 直到t1的10次循环全部执行完毕,线程才会开始处理t2()的代码,最终呈现串行执行的结果。

要实现预期的异步并行效果,只需将阻塞的同步等待替换为异步等待:
把Thread.Sleep(s)改为await Task.Delay(s),Task.Delay是真正的异步延迟操作,不会阻塞线程,线程可以在等待期间去执行其他任务(比如t2的代码)。

修改后的sleeper方法:

public async Task sleeper(int s)
{
    await Task.Delay(s);
}

修改后,当t1执行到await sleeper(5000)时会释放当前线程,线程可立即执行t2的代码,从而实现交替输出的并行效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:53:26