C# Task.WaitAll 的用法

news/2024/9/25 7:33:15/

目录

简介

1.WaitAll(Task[], Int32, CancellationToken)

2.WaitAll(Task[])

3.WaitAll(Task[], Int32)

4.WaitAll(Task[], CancellationToken)

5.WaitAll(Task[], TimeSpan)

结束


简介

Task.WaitAll 是 C# 中用于并行编程的一个的方法,它属于 System.Threading.Tasks 命名空间。主要作用是等待提供的所有 Task 对象完成其执行过程。通过使用 Task.WaitAll,开发者可以确保一组并行执行的任务全部完成后,再继续执行后续的代码。这对于需要等待多个异步操作同时完成以继续执行其他操作的场景非常有用。

Task.WaitAll 方法有多个重载版本,以适应不同的需求。最基本的版本接收一个 Task 对象的数组作为参数,并等待这个数组中的所有任务完成。如果所有任务都成功完成,则该方法正常返回;如果有任何任务在执行过程中抛出了异常,这些异常会被封装在 AggregateException 中并抛出。如果任务被取消,AggregateException 的 InnerExceptions 集合中会包含 OperationCanceledException。

Task.WaitAll 还提供了带有超时和取消令牌的重载方法,允许开发者在指定的时间间隔内等待所有任务完成,或者如果等待被取消,则提前退出等待。这些重载版本为处理超时和取消操作提供了更灵活的方式。

Task.WaitAll 方法适用于多种场景,如同时处理多个数据库查询、同时下载多个文件或执行任何需要并行处理的任务集合。通过并行处理,可以显著提高应用程序的响应速度和吞

打开你的项目,利用 Visual Studio 2022 反编译功能看看当前的 WaitAll 是那个对应的版本,比如下图,我用的是 .NetFramework 4.8 

官方文档:点击跳转

定义
命名空间:
System.Threading.Tasks
程序集:
System.Runtime.dll
等待提供的所有 Task 对象完成执行过程。

WaitAll(Task[], Int32, CancellationToken)等待提供的所有 Task 对象在指定的毫秒数内完成执行,或等到取消等待
WaitAll(Task[])等待提供的所有 Task 对象完成执行过程。
WaitAll(Task[], Int32)等待所有提供的 Task 在指定的毫秒数内完成执行
WaitAll(Task[], CancellationToken)等待提供的所有 Task 对象完成执行过程(除非取消等待)
WaitAll(Task[], TimeSpan)等待所有提供的可取消 Task 对象在指定的时间间隔内完成执行

1.WaitAll(Task[], Int32, CancellationToken)

等待提供的所有 Task 对象在指定的毫秒数内完成执行,或等到取消等待。

[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public static bool WaitAll (System.Threading.Tasks.Task[] tasks, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken);

参数
tasks  Task[]
要等待的 Task 实例的数组。

millisecondsTimeout  Int32
等待的毫秒数,或为 Infinite (-1),表示无限期等待。

cancellationToken  CancellationToken
等待任务完成期间要观察的 CancellationToken。

返回
Boolean
如果在分配的时间内所有 true 实例都已完成执行,则为 Task;否则为 false。

属性 UnsupportedOSPlatformAttribute


例外
ObjectDisposedException
tasks 中的一个或多个 Task 对象已释放。

ArgumentNullException
tasks 参数为 null。

AggregateException
至少一个 Task 实例已取消。 如果任务已取消,则 AggregateException 在其 InnerExceptions 集合中包含 OperationCanceledException。

- 或 -

在至少一个 Task 实例的执行过程中引发了异常。

ArgumentOutOfRangeException
millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。

ArgumentException
tasks 参数包含一个 null 元素。

OperationCanceledException
已取消 cancellationToken。

注解
参数 cancellationToken 用于取消等待操作。 取消任务是一项不同的操作,由 AggregateException 上面提到的 发出信号。

Task.WaitAll 方法是并行执行所有传入的任务,而不是按顺序一个接一个地执行。Task 是基于 .NET 的异步编程模型,利用多核 CPU 的优势来提高性能,并同时多个任务执行。

Task.WaitAll 在执行时,所有的任务会几乎同时启动,具体的执行顺序取决于线程调度和系统资源。系统会根据可用的线程和 CPU 核心来调度这些任务。这意味着,任务的完成顺序可能与它们在代码中添加到列表的顺序不同。

Task.WaitAll 方法会阻塞调用线程,直到所有任务都完成。

新建一个 .NET Framework 4.8 的 控制台项目,就当前的方法写一个案例:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;namespace task_test1
{internal class Program{static CancellationTokenSource cts = new CancellationTokenSource();static void Main(string[] args){int timeout = 1000;List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();taskList.Add(PingTest("https://github.com/"));taskList.Add(PingTest("https://www.csdn.net/"));taskList.Add(PingTest("https://www.zhihu.com/"));taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));taskList.Add(PingTest("https://www.baidu.com/"));Task<(string, bool)>[] tasks = taskList.ToArray();try{bool allCompleted = Task.WaitAll(tasks, timeout, cts.Token);Console.WriteLine("执行结果:{0}", allCompleted);foreach (var task in tasks){var tuple = task.Result;Console.WriteLine($"result:{tuple.Item2},url:{tuple.Item1}");}}catch (Exception ex){Console.WriteLine("错误:{0}", ex.Message);}Console.ReadKey();}static async Task<(string, bool)> PingTest(string ip){cts.Token.ThrowIfCancellationRequested();PingTool tool = new PingTool();bool result = await tool.Ping(ip, cts);return (ip, result);}}
}internal class PingTool
{public async Task<bool> Ping(string url, CancellationTokenSource cts){if (string.IsNullOrEmpty(url))return false;try{using (HttpClient client = new HttpClient()){client.Timeout = TimeSpan.FromSeconds(5);cts.Token.ThrowIfCancellationRequested();var response = await client.GetAsync(url, cts.Token);return response.IsSuccessStatusCode;}}catch (Exception){return false;}}
}

运行:

代码中 int timeout = 1000,也就是1秒,在超时的情况下,Task.WaitAll 会返回 false,但是5个 Task 依然全部执行了,所以,timeout 影响的也只有 task 的返回结果了

不超时会返回 true


 

2.WaitAll(Task[])

等待提供的所有 Task 对象完成执行过程。

[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public static void WaitAll (params System.Threading.Tasks.Task[] tasks);

参数

tasks  Task[]
要等待的 Task 实例的数组。

属性  UnsupportedOSPlatformAttribute


例外
ObjectDisposedException
tasks 中的一个或多个 Task 对象已释放。

ArgumentNullException
tasks 参数为 null。

ArgumentException
tasks 参数包含一个 null 元素。

AggregateException
至少一个 Task 实例已取消。 如果任务取消,则 AggregateException 异常在其 InnerExceptions 集合中包含 OperationCanceledException 异常。

- 或 -

在至少一个 Task 实例的执行过程中引发了异常
 

C# 案例:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;namespace task_test1
{internal class Program{static void Main(string[] args){List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();taskList.Add(PingTest("https://www.csdn.net/"));taskList.Add(PingTest("https://www.zhihu.com/"));taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));taskList.Add(PingTest("https://www.baidu.com/"));taskList.Add(PingTest("https://github.com/"));Task.WaitAll(taskList.ToArray());Console.ReadKey();}static async Task<(string, bool)> PingTest(string ip){PingTool tool = new PingTool();bool result = await tool.Ping(ip);Console.WriteLine("result:{0},时间:{1},url:{2}", result, DateTime.Now, ip);return (ip, result);}}
}internal class PingTool
{public async Task<bool> Ping(string url){if (string.IsNullOrEmpty(url))return false;try{using (HttpClient client = new HttpClient()){client.Timeout = TimeSpan.FromSeconds(5);var response = await client.GetAsync(url);return response.IsSuccessStatusCode;}}catch (System.Exception){return false;}}
}

运行:

3.WaitAll(Task[], Int32)

等待所有提供的 Task 在指定的毫秒数内完成执行。

[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public static bool WaitAll (System.Threading.Tasks.Task[] tasks, int millisecondsTimeout);

参数
tasks  Task[]
要等待的 Task 实例的数组。

millisecondsTimeout  Int32
等待的毫秒数,或为 Infinite (-1),表示无限期等待。

返回
Boolean
如果在分配的时间内所有 true 实例都已完成执行,则为 Task;否则为 false。

属性   UnsupportedOSPlatformAttribute


例外
ObjectDisposedException
tasks 中的一个或多个 Task 对象已释放。

ArgumentNullException
tasks 参数为 null。

AggregateException
至少一个 Task 实例已取消。 如果任务已取消,则 AggregateException 在其 InnerExceptions 集合中包含 OperationCanceledException。

- 或 -

在至少一个 Task 实例的执行过程中引发了异常。

ArgumentOutOfRangeException
millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。

ArgumentException
tasks 参数包含一个 null 元素。

C# 案例:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;namespace task_test1
{internal class Program{static void Main(string[] args){int timeout = 3000;List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();taskList.Add(PingTest("https://github.com/"));taskList.Add(PingTest("https://www.csdn.net/"));taskList.Add(PingTest("https://www.zhihu.com/"));taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));taskList.Add(PingTest("https://www.baidu.com/"));Task<(string, bool)>[] tasks = taskList.ToArray();bool allCompleted = Task.WaitAll(tasks, timeout);Console.WriteLine("执行结果:{0}", allCompleted);foreach (var task in tasks){var tuple = task.Result;Console.WriteLine($"result:{tuple.Item2},url:{tuple.Item1}");}Console.ReadKey();}static async Task<(string, bool)> PingTest(string ip){PingTool tool = new PingTool();bool result = await tool.Ping(ip);return (ip, result);}}
}internal class PingTool
{public async Task<bool> Ping(string url){if (string.IsNullOrEmpty(url))return false;try{using (HttpClient client = new HttpClient()){client.Timeout = TimeSpan.FromSeconds(5);var response = await client.GetAsync(url);return response.IsSuccessStatusCode;}}catch (System.Exception){return false;}}
}

运行:

4.WaitAll(Task[], CancellationToken)

等待提供的所有 Task 对象完成执行过程(除非取消等待)。

[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public static void WaitAll (System.Threading.Tasks.Task[] tasks, System.Threading.CancellationToken cancellationToken);

参数
tasks  Task[]
要等待的 Task 实例的数组。

cancellationToken  CancellationToken
等待任务完成期间要观察的 CancellationToken。

属性  UnsupportedOSPlatformAttribute


例外
OperationCanceledException
已取消 cancellationToken。

ArgumentNullException
tasks 参数为 null。

AggregateException
至少一个 Task 实例已取消。 如果任务已取消,则 AggregateException 在其 InnerExceptions 集合中包含 OperationCanceledException。

- 或 -

在至少一个 Task 实例的执行过程中引发了异常。

ArgumentException
tasks 参数包含一个 null 元素。

ObjectDisposedException
tasks 中的一个或多个 Task 对象已释放。

注解
参数 cancellationToken 用于取消等待操作。 取消任务是一项不同的操作,由 如上所述的 发出信号 AggregateException 。

关于取消任务为什么后续依然执行了,请参考第1节的解释

C# 案例:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;namespace task_test1
{internal class Program{static CancellationTokenSource cts = new CancellationTokenSource();static void Main(string[] args){List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();taskList.Add(PingTest("https://github.com/"));taskList.Add(PingTest("https://www.csdn.net/"));taskList.Add(PingTest("https://www.zhihu.com/"));taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));taskList.Add(PingTest("https://www.baidu.com/"));Task<(string, bool)>[] tasks = taskList.ToArray();Task.Run(() =>{Thread.Sleep(100);Console.WriteLine("取消任务");cts.Cancel();});Console.WriteLine("开始执行任务");try{Task.WaitAll(tasks, cts.Token);}catch (Exception ex){Console.WriteLine("错误:{0}", ex.Message);}Console.ReadKey();}static async Task<(string, bool)> PingTest(string ip){//方法 Task.WaitAll 执行任务会同时执行所有的Task,并等待任务完成//而不是一个个按顺序来执行,然后等待结果,所以注释的代码无效//if (cts.Token.IsCancellationRequested) //{//    Console.WriteLine($"Task for {ip} was cancelled before execution.");//    return (ip, false);//}//cts.Token.ThrowIfCancellationRequested();PingTool tool = new PingTool();bool result = await tool.Ping(ip, cts);Console.WriteLine("result:{0},url:{1}", result, ip);return (ip, result);}}
}internal class PingTool
{public async Task<bool> Ping(string url, CancellationTokenSource cts){if (string.IsNullOrEmpty(url))return false;try{using (HttpClient client = new HttpClient()){client.Timeout = TimeSpan.FromSeconds(5);cts.Token.ThrowIfCancellationRequested();var response = await client.GetAsync(url, cts.Token);return response.IsSuccessStatusCode;}}catch (Exception){return false;}}
}

运行:

5.WaitAll(Task[], TimeSpan)

等待所有提供的可取消 Task 对象在指定的时间间隔内完成执行。

[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public static bool WaitAll (System.Threading.Tasks.Task[] tasks, TimeSpan timeout);

参数
tasks  Task[]
要等待的 Task 实例的数组。

timeout  TimeSpan
表示等待毫秒数的 TimeSpan,或表示 -1 毫秒(无限期等待)的 TimeSpan。

返回
Boolean
如果在分配的时间内所有 true 实例都已完成执行,则为 Task;否则为 false。

属性  UnsupportedOSPlatformAttribute


例外
ObjectDisposedException
tasks 中的一个或多个 Task 对象已释放。

ArgumentNullException
tasks 参数为 null。

AggregateException
至少一个 Task 实例已取消。 如果任务已取消,则 AggregateException 在其 InnerExceptions 集合中包含 OperationCanceledException。

- 或 -

在至少一个 Task 实例的执行过程中引发了异常。

ArgumentOutOfRangeException
timeout 为 -1 毫秒以外的负数,表示无限期超时。

- 或 -

timeout 大于 Int32.MaxValue。

ArgumentException
tasks 参数包含一个 null 元素。
 

C# 案例:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;namespace task_test1
{internal class Program{static void Main(string[] args){List<Task<(string, bool)>> taskList = new List<Task<(string, bool)>>();taskList.Add(PingTest("https://github.com/"));taskList.Add(PingTest("https://www.csdn.net/"));taskList.Add(PingTest("https://www.zhihu.com/"));taskList.Add(PingTest("https://www.microsoft.com/zh-cn/"));taskList.Add(PingTest("https://www.baidu.com/"));Task<(string, bool)>[] tasks = taskList.ToArray();bool allCompleted = Task.WaitAll(tasks, TimeSpan.FromSeconds(1));Console.WriteLine("执行结果:{0}", allCompleted);foreach (var task in tasks){var tuple = task.Result;Console.WriteLine($"result:{tuple.Item2},url:{tuple.Item1}");}Console.ReadKey();}static async Task<(string, bool)> PingTest(string ip){PingTool tool = new PingTool();bool result = await tool.Ping(ip);return (ip, result);}}
}internal class PingTool
{public async Task<bool> Ping(string url){if (string.IsNullOrEmpty(url))return false;try{using (HttpClient client = new HttpClient()){client.Timeout = TimeSpan.FromSeconds(5);var response = await client.GetAsync(url);return response.IsSuccessStatusCode;}}catch (System.Exception){return false;}}
}

运行:

结束

如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢

end


http://www.ppmy.cn/news/1502116.html

相关文章

十日Python项目——第四日(用户中心—收货地址)

#前言&#xff1a; 在最近十天我会用Python做一个购物类项目&#xff0c;会用到DjangoMysqlRedisVue等。 今天是第四天&#xff0c;主要负责撰写用户中心部分的收货地址部分。若是有不懂大家可以先阅读我的前三篇博客以能够顺承。 若是大家基础有不懂的&#xff0c;小编前面…

使用JTAG时报如下错

* JLink Info: TotalIRLen ?, IRPrint 0x..000000000000000000000000 * JLink Info: Failed to identify target. Resetting via Reset pin and trying again. * JLink Info: TotalIRLen ?, IRPrint 0x..000000000000000000000000 Error: Flash Download failed - Targ…

WordPress建站:如何使用ChemiCloud搭建外贸独立站

以前自行搭建一个网站&#xff0c;不懂一点技术那是很难完成的&#xff0c;现如今WordPress的出现极大地降低了搭建网站的技术门槛&#xff0c;不需要懂任何代码&#xff0c;只需按步骤操作就行。WordPress 是一个非常流行的开源内容管理系统&#xff08;CMS&#xff09;&#…

全栈嵌入式C++、STM32、Modbus、FreeRTOS和MQTT协议:工业物联网(IIoT)可视化系统设计思路(附部分代码解析)

项目概述 随着工业4.0时代的到来&#xff0c;工业物联网&#xff08;IIoT&#xff09;在提高生产效率、降低运营成本和实现智能制造方面得到了广泛应用。本项目旨在开发一个全面的工业物联网监控系统&#xff0c;能够实时监测设备的温度、压力、振动和电流等参数&#xff0c;并…

陀螺仪LSM6DSOW开发(5)----MotionFX库解析空间坐标

陀螺仪LSM6DSOW开发.5--MotionFX库解析空间坐标 概述视频教学样品申请源码下载硬件准备开启CRC串口设置开启X-CUBE-MEMS1速率选择初始化定义MotionFX文件卡尔曼滤波算法主程序执行流程欧拉角简介演示 概述 本文将探讨如何使用MotionFX库解析空间坐标。MotionFX库是一种用于传感…

【初阶数据结构篇】二叉树算法题

文章目录 二叉树算法题前言单值二叉树相同的树对称二叉树另一棵树的子树二叉树的前序遍历 二叉树算法题 前言 本篇的算法题涉及到链式结构二叉树的实现方法可参考&#xff1a;二叉链实现方法上篇二叉链实现方法下篇 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;…

构建高效的Python自定义日志系统:深入探索logging模块的高级功能

构建高效的Python自定义日志系统&#xff1a;深入探索logging模块的高级功能 在Python开发过程中&#xff0c;日志记录是一项至关重要的任务。它不仅帮助开发者监控应用运行状态&#xff0c;还能在出现问题时提供宝贵的调试信息。Python标准库中的logging模块提供了灵活且强大…

使用Selenium爬虫批量下载AlphaFold数据库中的PDB文件

注意&#xff1a;本方法使用了python&#xff0c;下载速度一般&#xff0c;如果需要更快的大批量下载可以考虑使用其他方法&#xff0c;例如FTP Alphafold数据库其实提供了许多物种的蛋白质组&#xff1a; AlphaFold Protein Structure Database 但是如果你搜索的物种不在这个…