1. Task 类介绍
在C#中,Task类用于执行并行或异步操作,并返回结果或不返回结果。在进行异步编程时,我们常常使用Task来处理异步任务。Task类提供了一系列的方法和属性,其中包括Task.WhenAll和Task.WhenAny。
2. Task.WhenAll方法
Task.WhenAll方法用于等待并行执行的多个任务全部完成。
2.1 方法签名
public static Task WhenAll(IEnumerable<Task> tasks);
当调用Task.WhenAll方法时,传入一个IEnumerable<Task>集合,该集合包含需要等待的多个任务。
2.2 方法返回值
Task.WhenAll方法会返回一个Task,该Task在所有传入的任务都完成后完成。
2.3 示例代码
Task task1 = Task.Run(() => { /* 执行任务1 */ });
Task task2 = Task.Run(() => { /* 执行任务2 */ });
Task task3 = Task.Run(() => { /* 执行任务3 */ });
Task<int> task4 = Task.Run(() => { /* 执行任务4,返回结果 */ });
await Task.WhenAll(task1, task2, task3, task4);
上述示例代码中,我们定义了四个任务,其中task1、task2和task3是不返回结果的任务,task4是一个返回int类型结果的任务。通过调用Task.WhenAll方法,并传入这四个任务,我们可以等待所有任务都完成。
使用Task.WhenAll方法的一个注意点是,当传入的任务中存在异常时,Task.WhenAll方法会将所有的异常进行聚合,并以AggregateException的形式抛出。
3. Task.WhenAny方法
Task.WhenAny方法用于等待并行执行的多个任务中的任意一个完成。
3.1 方法签名
public static Task<Task> WhenAny(IEnumerable<Task> tasks);
Task.WhenAny方法也需要传入一个IEnumerable<Task>集合,该集合包含需要等待的多个任务。
3.2 方法返回值
Task.WhenAny方法返回一个Task<Task>,该Task<Task>代表已完成的任务中的任意一个。
3.3 示例代码
Task task1 = Task.Run(() => { /* 执行任务1 */ });
Task task2 = Task.Run(() => { /* 执行任务2 */ });
Task task3 = Task.Run(() => { /* 执行任务3 */ });
Task<int> task4 = Task.Run(() => { /* 执行任务4,返回结果 */ });
Task<Task> firstCompletedTask = await Task.WhenAny(task1, task2, task3, task4);
Task completedTask = await firstCompletedTask;
上述示例代码中,我们定义了四个任务,同样地,task1、task2和task3是不返回结果的任务,task4是一个返回int类型结果的任务。通过调用Task.WhenAny方法,并传入这四个任务,我们可以等待任意一个任务完成。
需要注意的是,通过Task.WhenAny方法返回的Task<Task>的结果只是其中一个已完成的任务,我们还需要通过await获取到该已完成任务。
4. 总结
Task类是C#中异步编程的重要工具之一,在处理并行或异步操作时,我们常常会用到Task.WhenAll和Task.WhenAny方法。Task.WhenAll方法用于等待多个任务都完成,而Task.WhenAny方法用于等待任意一个任务完成。同时,需要注意的是,当传入的任务中存在异常时,Task.WhenAll方法会将所有异常进行聚合,并以AggregateException的形式抛出。
使用Task类相关的方法可以提升并行执行和异步操作的效率和性能,它们在多线程编程和并发编程中有着广泛的应用。