当前位置: 首页 > news >正文

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • BGP选路之Local Preference
  • table car vs. table cars:数据库命名用单数还是复数?
  • OpenCV图像滤波(1)双边滤波函数bilateralFilter的使用
  • 小规模的LLMS
  • C# 使用pythonnet 迁入 python 初始化错误解决办法
  • GO版本更新
  • [Meachines] Lame smbd3.0-RCE
  • 一文解决 | Linux(Ubuntn)系统安装 | 硬盘挂载 | 用户创建 | 生信分析配置
  • 可能是目前最全面的前端提测/自测标准
  • AI有关的学习和python
  • 数据结构-C语言-排序(4)
  • 测试工作中常听到的名词解释 : )
  • Java中的object类与objects类
  • paramiko 模块
  • 微信小程序-自定义tabBar
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 230. Kth Smallest Element in a BST
  • es6
  • Git同步原始仓库到Fork仓库中
  • overflow: hidden IE7无效
  • spring-boot List转Page
  • 编写符合Python风格的对象
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 前端_面试
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 一个项目push到多个远程Git仓库
  • 《天龙八部3D》Unity技术方案揭秘
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #Linux(Source Insight安装及工程建立)
  • #职场发展#其他
  • (02)Hive SQL编译成MapReduce任务的过程
  • (35)远程识别(又称无人机识别)(二)
  • (4)Elastix图像配准:3D图像
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (7)svelte 教程: Props(属性)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (分布式缓存)Redis持久化
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (算法)硬币问题
  • (转)创业的注意事项
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .net8.0与halcon编程环境构建
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • /etc/fstab 只读无法修改的解决办法
  • /tmp目录下出现system-private文件夹解决方法
  • @Transactional类内部访问失效原因详解
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [EFI]ASUS EX-B365M-V5 Gold G5400 CPU电脑 Hackintosh 黑苹果引导文件