编辑
2025-10-11
C#
00

目录

Task.WaitAny 的特点
使用 Task.WaitAny 的基本语法
示例:使用 Task.WaitAny 等待任务完成
代码解析
示例:使用超时参数
代码解析
示例:处理完成的任务结果
代码解析
总结

在现代 C# 多线程编程中,Task 类是处理异步操作的重要工具。Task.WaitAny 方法允许你等待多个 Task 之一完成,这在处理并行任务时非常有用。本文将详细介绍 Task.WaitAny 的特点、用法,并提供多个示例以展示其应用。

Task.WaitAny 的特点

  • 等待任意任务完成Task.WaitAny 可以接收一个任务数组,并在任一任务完成时立即返回。这在需要处理并行任务的场合提供灵活性。
  • 非阻塞等待:虽然这个方法等待一个或多个任务完成,但它能以非阻塞的方式执行其他操作,帮助提高应用的响应性。
  • 返回完成任务的索引:当某个任务完成时,Task.WaitAny 返回完成任务在任务数组中的索引。
  • 支持超时Task.WaitAny 可以设置超时参数,指定等待时间,超时后将返回超时状态。

使用 Task.WaitAny 的基本语法

以下是 Task.WaitAny 的基本用法示例:

C#
using System.Threading.Tasks; Task[] tasks = new Task[3]; // 创建任务 int completedTaskIndex = Task.WaitAny(tasks); // 等待任意任务完成

示例:使用 Task.WaitAny 等待任务完成

以下示例展示了如何创建多个任务,并使用 Task.WaitAny 等待其中一个完成。

C#
namespace AppWaitAny { internal class Program { static void Main(string[] args) { Task[] tasks = new Task[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; tasks[i] = Task.Run(() => { int delay = new Random().Next(1000, 5000); // 随机延迟 Thread.Sleep(delay); Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒"); }); } // 等待任意任务完成 int completedTaskIndex = Task.WaitAny(tasks); Console.WriteLine($"任务 {completedTaskIndex + 1} 已完成。"); // 等待其他任务完成 Task.WaitAll(tasks); Console.WriteLine("所有任务已完成。"); } } }

image.png

代码解析

  1. 创建任务数组:初始化一个 Task 类型的数组,用于存储并发任务。
  2. 启动任务:使用 Task.Run() 方法启动多个任务,每个任务随机延迟一段时间后完成,并输出其完成信息。
  3. 等待任意任务完成
    • 使用 Task.WaitAny(tasks) 等待任意一个任务完成。
    • 输出已完成任务的索引。
  4. 等待所有任务完成:使用 Task.WaitAll(tasks) 确保所有任务都已完成。

示例:使用超时参数

可以在 Task.WaitAny 中设置超时,以限制等待时间。以下示例展示了如何使用超时参数:

C#
using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task[] tasks = new Task[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; tasks[i] = Task.Run(() => { Thread.Sleep(4000); // 每个任务都延迟 4 秒 Console.WriteLine($"任务 {taskId} 完成"); }); } // 设置超时为 2 秒 int completedTaskIndex = Task.WaitAny(tasks, 2000); if (completedTaskIndex == -1) { Console.WriteLine("没有任务在指定时间内完成。"); } else { Console.WriteLine($"任务 {completedTaskIndex + 1} 已完成。"); } // 等待所有任务完成 Task.WaitAll(tasks); Console.WriteLine("所有任务已完成。"); } }

image.png

代码解析

  1. 创建任务:启动 3 个任务,它们都会睡眠 4 秒后完成。
  2. 设置超时
    • 调用 Task.WaitAny(tasks, 2000),等待 2 秒钟看看是否有任务完成。
    • 判断返回值,如果返回-1,表示在超时时间内没有任务完成。
  3. 等待所有任务完成:调用 Task.WaitAll(tasks) 确保所有任务完成。

示例:处理完成的任务结果

在实际应用中,我们可能需要处理完成的任务的结果。以下示例展示了如何获取所有任务的结果。

C#
using System; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task<int>[] tasks = new Task<int>[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; tasks[i] = Task.Run(() => { Random random = new Random(); int delay = random.Next(1000, 5000); // 随机延迟 Thread.Sleep(delay); Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒"); return delay; // 返回耗时 }); } // 等待任意任务完成 int completedTaskIndex = Task.WaitAny(tasks); Console.WriteLine($"任务 {completedTaskIndex + 1} 已完成。"); // 获取所有任务的结果 foreach (var task in tasks) { Console.WriteLine($"任务耗时: {task.Result} 毫秒"); } Console.WriteLine("所有任务已完成。"); } }

image.png

代码解析

  1. 创建返回值任务:使用 Task<int> 数组存储任务,并返回每个任务的耗时。
  2. 启动任务:任务在完成后会返回随机耗时的值。
  3. 等待任意任务完成:使用 Task.WaitAny 等待任意任务完成。
  4. 输出任务结果:循环所有任务,使用 task.Result 获取每个任务的耗时。

总结

Task.WaitAny 是处理异步任务的强大工具,它允许你等待多个任务中的任何一个完成,而不会阻塞其他操作。在高并发场景中,能够有效提升程序的响应性。通过上述示例,我们可以看到在实际应用中如何利用 Task.WaitAny 管理和处理并发任务。合理使用 Task.WaitAny 可以显著增强多线程程序的效率和可维护性。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!