C#怎么使用TaskWhenAll并行等待多个异步任务

来源:编程学习作者:老毕头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#怎么使用TaskWhenAll并行等待多个异步任务》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么使用TaskWhenAll并行等待多个异步任务》有用,将其分享出去将是对创作者最好的鼓励。

在C#异步编程场景中,经常需要同时执行多个独立的异步操作,比如同时调用多个外部接口获取数据、并行处理多个文件读写任务等。如果逐个等待这些异步任务完成,总耗时将是所有任务耗时的总和,而使用Task.WhenAll方法可以让所有任务并行执行,仅等待最慢的那个任务完成,极大提升程序运行效率。

C#怎么使用TaskWhenAll并行等待多个异步任务

Task.WhenAll基本用法

Task.WhenAll是System.Threading.Tasks命名空间下的静态方法,它接收一个任务集合作为参数,返回一个代表所有任务完成的新任务。当传入的所有任务都完成时,返回的任务才会进入完成状态。

等待无返回值的多个异步任务

如果多个异步任务都没有返回值,可以直接将任务集合传入Task.WhenAll,等待所有任务执行完毕即可。

using System;
using System.Threading.Tasks;

class Program
{
    // 模拟无返回值的异步任务
    static async Task AsyncTask1()
    {
        await Task.Delay(1000); // 模拟耗时1秒的操作
        Console.WriteLine("任务1执行完成");
    }

    static async Task AsyncTask2()
    {
        await Task.Delay(1500); // 模拟耗时1.5秒的操作
        Console.WriteLine("任务2执行完成");
    }

    static async Task AsyncTask3()
    {
        await Task.Delay(800); // 模拟耗时0.8秒的操作
        Console.WriteLine("任务3执行完成");
    }

    static async Task Main(string[] args)
    {
        // 创建三个异步任务
        Task task1 = AsyncTask1();
        Task task2 = AsyncTask2();
        Task task3 = AsyncTask3();

        // 并行等待所有任务完成
        await Task.WhenAll(task1, task2, task3);
        Console.WriteLine("所有无返回值任务都执行完毕");
    }
}

上述代码中三个任务并行执行,总耗时约为最慢的任务耗时1.5秒,而不是三个任务耗时相加的3.3秒。

等待有返回值的多个异步任务

如果异步任务有返回值,Task.WhenAll会将所有任务的返回值收集到一个数组中,按照传入任务的顺序返回结果。

using System;
using System.Threading.Tasks;

class Program
{
    // 模拟有返回值的异步任务
    static async Task<int> GetDataAsync1()
    {
        await Task.Delay(1000);
        return 100;
    }

    static async Task<int> GetDataAsync2()
    {
        await Task.Delay(1200);
        return 200;
    }

    static async Task<int> GetDataAsync3()
    {
        await Task.Delay(900);
        return 300;
    }

    static async Task Main(string[] args)
    {
        // 创建三个有返回值的异步任务
        Task<int> task1 = GetDataAsync1();
        Task<int> task2 = GetDataAsync2();
        Task<int> task3 = GetDataAsync3();

        // 等待所有任务完成并获取结果
        int[] results = await Task.WhenAll(task1, task2, task3);
        Console.WriteLine($"所有任务结果:{string.Join(",", results)}"); // 输出 100,200,300
    }
}

Task.WhenAll的异常处理

当使用Task.WhenAll等待多个任务时,如果其中某个任务抛出异常,返回的任务会进入故障状态,异常会被包装在AggregateException中。需要注意,只有所有任务都完成后,异常才会被抛出,不会因为某个任务异常就立即中断等待。

using System;
using System.Threading.Tasks;

class Program
{
    static async Task TaskWithException()
    {
        await Task.Delay(500);
        throw new InvalidOperationException("任务执行出错");
    }

    static async Task NormalTask()
    {
        await Task.Delay(1000);
        Console.WriteLine("正常任务执行完成");
    }

    static async Task Main(string[] args)
    {
        Task task1 = TaskWithException();
        Task task2 = NormalTask();

        try
        {
            await Task.WhenAll(task1, task2);
        }
        catch (AggregateException ex)
        {
            // 遍历所有内部异常
            foreach (var innerEx in ex.InnerExceptions)
            {
                Console.WriteLine($"捕获到异常:{innerEx.Message}");
            }
        }
        catch (Exception ex)
        {
            // 如果只传入一个任务,可能直接抛出对应异常
            Console.WriteLine($"其他异常:{ex.Message}");
        }
    }
}

上述代码中,即使第一个任务抛出异常,程序还是会等待第二个任务执行完成,之后才会进入异常处理逻辑,不会提前中断等待。

使用注意事项

  • 传入Task.WhenAll的任务集合不能为空,否则会抛出ArgumentException异常。
  • 不要在启动任务之前就调用Task.WhenAll,否则会立即返回一个已经完成的任务,无法达到并行等待的效果。
  • 如果多个任务之间存在依赖关系,不适合使用Task.WhenAll,应该按照依赖顺序逐个执行。
  • 当任务数量非常多时,需要考虑系统的资源承载能力,避免同时启动过多任务导致资源耗尽。

适用场景总结

Task.WhenAll适合所有任务相互独立、没有依赖关系、可以并行执行的场景,比如:

  • 同时调用多个第三方接口获取数据,最后汇总结果。
  • 并行处理多个独立的文件、图片处理任务。
  • 同时向多个消息队列发送消息,等待所有发送完成。

合理使用Task.WhenAll可以有效提升C#异步程序的执行效率,减少不必要的等待时间,是进阶异步编程必须掌握的核心方法。

C#TaskWhenAll异步任务并行等待修改时间:2026-07-24 03:24:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。