在 C# 的多线程编程中,Task
类是处理异步操作的重要赋能,而 Task.WaitAll
方法则用于等待一组任务的完成。这在处理多个并行任务时非常有用,特别是在需要确保所有并发操作完成之前继续执行的场景中。本文将详细介绍 Task.WaitAll
的特点、用法,并提供多个示例以展示其应用。
这是个好玩意,以前thread中要同步这个费了事。
Task.WaitAll
的特点Task.WaitAll
方法接收一个任务数组,并阻塞当前线程,直到所有任务完成。WaitAll
将会抛出相应的异常。Task.WaitAll
的基本语法以下是 Task.WaitAll
的基本用法示例:
C#using System.Threading.Tasks;
Task[] tasks = new Task[3];
// 创建任务
Task.WaitAll(tasks); // 等待所有任务完成
Task.WaitAll
等待多个任务完成以下示例展示了如何创建多个任务,并使用 Task.WaitAll
等待所有任务完成。
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; // 为任务分配ID
tasks[i] = Task.Run(() => {
int delay = new Random().Next(1000, 5000); // 随机延迟
Thread.Sleep(delay); // 模拟耗时操作
Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒");
});
}
// 等待所有任务完成
Task.WaitAll(tasks);
Console.WriteLine("所有任务已完成。");
}
}
Task
类型的数组,用于存储并发任务。Task.Run()
方法启动多个任务,每个任务随机延迟一段时间后完成,并输出其完成信息。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; // 为任务分配ID
tasks[i] = Task.Run(() => {
int delay = new Random().Next(1000, 5000); // 随机延迟
Thread.Sleep(delay); // 模拟耗时操作
Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒");
return delay; // 返回任务的耗时
});
}
// 等待所有任务完成
Task.WaitAll(tasks);
// 获取并输出所有任务的结果
foreach (var task in tasks) {
Console.WriteLine($"任务耗时: {task.Result} 毫秒");
}
Console.WriteLine("所有任务已完成。");
}
}
Task<int>
数组存储任务,并返回每个任务的耗时。Task.WaitAll(tasks)
等待所有任务完成。task.Result
获取每个任务的耗时。在多个任务并行执行时,任何一个任务抛出的异常都可以被捕获到。以下示例展示了如何处理任务中的异常。
C#using System;
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; // 为任务分配ID
tasks[i] = Task.Run(() => {
if (taskId == 2) {
throw new Exception($"任务 {taskId} 遇到错误!"); // 故意抛出异常
}
int delay = new Random().Next(1000, 5000); // 随机延迟
Thread.Sleep(delay); // 模拟耗时操作
Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒");
});
}
try {
// 等待所有任务完成
Task.WaitAll(tasks);
} catch (AggregateException ex) {
foreach (var inner in ex.InnerExceptions) {
Console.WriteLine(inner.Message); // 输出异常信息
}
}
Console.WriteLine("所有任务处理完成。");
}
}
try-catch
块包裹 Task.WaitAll(tasks)
,捕获 AggregateException
,该异常包含所有任务引发的异常信息。Task.WaitAll
的注意事项Task.WaitAll
在所有任务完成之前会阻塞当前线程,确保在使用前已考虑对主线程的响应性。Task.WaitAll
时应注意捕获异常,因为任何未处理的异常会导致 AggregateException
的抛出。Task.WaitAll
是 C# 中非常有用的工具,能够等待多个异步任务完成,非常适合需要确保所有并行工作完成的场景。通过上述示例,我们可以看到在实际应用中如何利用 Task.WaitAll
管理和处理并发任务。合理使用 Task.WaitAll
可以显著提高多线程程序的可靠性和效率,尤其在处理多个异步操作时,它为任务的组织和管理提供了极大的便利。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!