C# Task.WaitAll 的用法

目录

简介

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.mzph.cn/bicheng/50968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DjangoRF-5-用户管理-users接口

1、创建模型&#xff0c;user模型之前创建过了&#xff0c;继承了原有的模型类 2、序列化器 在 users/serializers.py 模块中添加&#xff1a; class UserSerializer(serializers.ModelSerializer):class Meta:model Userfields [id, username, password, mobile, email, is…

【简单讲解Perl语言】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

基于微信小程序+SpringBoot+Vue的核酸检测服务系统(带1w+文档)

基于微信小程序SpringBootVue的核酸检测服务系统(带1w文档) 基于微信小程序SpringBootVue的核酸检测服务系统(带1w文档) 在目前的情况下&#xff0c;可以引进一款医院核酸检测服务系统这样的现代化管理工具&#xff0c;这个工具就是解决上述问题的最好的解决方案。它不仅可以实…

20240727生活沉思------------关于报考软考高级架构师

软考高级架构师 软考高级架构师 缴费 主要是报的千峰 1880元。 相对来说还算可以吧。。。其他也没给我机会选择啊 备考 我现在开始备考&#xff0c;考试时间2024年11月。 今天是正式开始7.27号。 给大家看看接下来我的课程安排&#xff1a; 额&#xff0c;还是满满当当的…

日入800+小红书AI表情包项目拆解

一个高考结束之后&#xff0c;进入暑假&#xff0c;只要有手就能做的AI搞钱项目&#xff0c;不到2个月的时间在小某书上成功涨粉5w&#xff0c;通过发布广告&#xff0c;一条广告甚至还能赚到2000元&#xff1b; 只要有市场需求就可以制作这种表情包快速搞钱&#xff0c;上手非…

openmv 学习笔记(24电赛笔记)

模版匹配 模版匹配是一种计算机视觉技术&#xff0c;用于图像或者视频中查找特定的模版或者对象&#xff0c;查找模版可以是数字或者是物体&#xff0c;技术通过在目标图像中寻找与模版图像相似的区域来实现匹配。这种技术最早起源在 20世纪70年代 的图像处理领域。 使用模版匹…

网络编程总复习

TCP的创建&#xff1a; 服务器端 &#xff1a; 客户端&#xff1a;

【计算机网络】IP分片实验

一&#xff1a;实验目的 1&#xff1a;理解IP数据报分片的工作原理。 2&#xff1a;理解IP协议报文类型和格式。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS-C服务器、网线、Windows 2019/2003操作系统的计算机等。 软件&#xff1a;记事本、WireShark、Chrom…

倒计时11天,生物发酵行业盛宴即将在沪召开!

随着生物科技领域的蓬勃发展&#xff0c;2024上海生物发酵展的召开已经进入倒计时阶段&#xff0c;距离这场生物发酵产业的年度盛事仅剩11天。作为行业内备受瞩目的展会&#xff0c;它不仅汇聚了全球顶尖的生物发酵技术、产品与服务&#xff0c;更是一个探讨行业趋势、促进合作…

c++语言学习注意事项

当学习C语言时&#xff0c;有几个重要的注意事项可以帮助初学者更有效地掌握这门强大的编程语言&#xff1a; 1. 理解基本概念和语法 C 是一门复杂且功能强大的编程语言&#xff0c;因此理解其基本概念和语法至关重要。初学者应该重点掌握以下几个方面&#xff1a; 基本语法和…

最小二乘法公式推导

微积分和线性代数碰撞的数学盛宴&#xff1a;最小二乘法公式推导&#xff01;_哔哩哔哩_bilibili 递归最小二乘法与参数辨识_哔哩哔哩_bilibili 笔记

护眼灯有没有护眼的效果?一文揭秘用护眼灯到底好不好

护眼灯有没有护眼的效果&#xff1f;在现在这个时代&#xff0c;无论是在学习还是办公&#xff0c;都很难离开一款好用的台灯&#xff0c;所以&#xff0c;为了避免会挑选到质量不好的台灯&#xff0c;我们应该要先避开一些网红小品牌&#xff0c;优先选择有专业技术支持的&…

数据库作业四

1. 修改 student 表中年龄&#xff08; sage &#xff09;字段属性&#xff0c;数据类型由 int 改变为 smallint &#xff1a; ALTER TABLE student MODIFY Sage SMALLINT; 2. 为 Course 表中 Cno 课程号字段设置索引&#xff0c;并查看索引&#xff1a; ALTER TABLE…

JS+H5在线文心AI聊天(第三方接口)

源码在最后面 调用的不是文心官方接口 可以正常聊天 有打字动画 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-s…

科技与占星的融合:AI 智能占星师

本文由 ChatMoney团队出品 在科技的前沿领域&#xff0c;诞生了一位独特的存在——AI占星师。它并非传统意义上的占星师&#xff0c;而是融合了先进的人工智能技术与神秘的占星学知识。 这能够凭借其强大的数据分析能力和精准的算法&#xff0c;对星辰的排列和宇宙的能量进行深…

VLC输出NDI媒体流

目录 1. 下载安装VLC Play 2. 首先在电脑上安装NDI Tools 3. 运行VLC进行输出配置 4. 播放视频 5. 验证 (1)用Studio Monitor验证 (2)用OBS验证 NDI(Network Device Interface)即网络设备接口,是由美国 NewTek 公司开发的免费标准,它可使兼容的视频产品以高质量…

爬虫 APP 逆向 ---> 粉笔考研

环境&#xff1a; 粉笔考研 v6.3.15&#xff1a;https://www.wandoujia.com/apps/1220941/history_v6031500雷电9 模拟器&#xff1a;https://www.ldmnq.com/安装 magisk&#xff1a;https://blog.csdn.net/Ruaki/article/details/135580772安装 Dia 插件 (作用&#xff1a;禁…

RT-Thread debug 卡死在Stm32_putc问题分析解决

问题和解决方法 找了块开发板玩RT-Thread&#xff0c;一顿骚操作之后&#xff0c;发现debug就卡死在Stm32_putc(不稳定&#xff0c;反复重新上下电&#xff0c;重来有时候卡死有时候不卡死)&#xff0c;卡死情况如下图&#xff1a; 先最后的解决方法&#xff1a;取消调默认的内…

Qt学习--对象树的概念

文章目录 QPushButton 按钮Qt中对象树的概念封装自定义控件 QPushButton 按钮 学习对象树之前&#xff0c;我们得先学习基本控件的创建。创建一个按钮 创建一个按钮&#xff1a;第一种方法 // 创建一个按钮QPushButton *btn new QPushButton;// 设置控件的父对象btn->setP…

文本解码原理--MindNLP

前言 根据前文预测下一个单词 一个文本序列的概率分布可以分解为每个词基于其上文的条件概率的乘积 Greedy search 在每个时间步&#x1d461;都简单地选择概率最高的词作为当前输出词: &#x1d464;&#x1d461;&#x1d44e;&#x1d45f;&#x1d454;&#x1d45a;&am…