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

同步与异步:.NET 中的 Task.WaitAll 和 Task.WhenAll

在 C# 中,异步编程通常涉及同时运行多个任务。处理多个任务的两种常见方法是 Task.WaitAll 和 Task.WhenAll。虽然它们看起来很相似,但它们的用途不同,并且用于不同的场景。本文探讨了 Task.WaitAll 和 Task.WhenAll 之间的区别,并通过实际示例来说明它们的用法。

什么是 Task.WaitAll?

Task.WaitAll 是一种同步方法,它会阻塞调用线程,直到所有提供的任务都已完成。当您需要确保一组任务在继续之前已完成时,该方法很有用,但它以阻塞方式执行,这意味着调用 Task.WaitAll 的线程会被占用,直到所有任务都完成为止。

Task.WaitAll 的示例用法

using System;
using System.Threading.Tasks;
class Program
{static void Main(){Task task1 = Task.Run(() => PerformTask(1));Task task2 = Task.Run(() => PerformTask(2));Task task3 = Task.Run(() => PerformTask(3));Task.WaitAll(task1, task2, task3); // Blocks until all tasks completeConsole.WriteLine("All tasks completed.");}static void PerformTask(int taskId){Console.WriteLine($"Task {taskId} starting.");Task.Delay(1000).Wait(); // Simulate workConsole.WriteLine($"Task {taskId} completed.");}
}

在此示例中,Task.WaitAll 阻止主线程,直到所有三个任务都完成。

什么是 Task.WhenAll?

Task.WhenAll 是一种异步方法,当所有提供的任务都完成后,该方法将返回单个任务。与 Task.WaitAll 不同,它不会阻止调用线程。相反,它允许调用代码继续异步执行。

Task.WhenAll 的示例用法

using System;
using System.Threading.Tasks;
class Program
{static async Task Main(){Task task1 = Task.Run(() => PerformTask(1));Task task2 = Task.Run(() => PerformTask(2));Task task3 = Task.Run(() => PerformTask(3));await Task.WhenAll(task1, task2, task3); // Waits for all tasks to complete asynchronouslyConsole.WriteLine("All tasks completed.");}static void PerformTask(int taskId){Console.WriteLine($"Task {taskId} starting.");Task.Delay(1000).Wait(); // Simulate workConsole.WriteLine($"Task {taskId} completed.");}
}

在此示例中,Task.WhenAll 允许主方法等待所有任务的完成,而不会阻塞调用线程。

主要区别

阻塞与非阻塞

  1. 阻塞与非阻塞
  • Task.WaitAll:阻止调用线程,直到所有任务完成。
  • Task.WhenAll:返回一个可以等待的任务,允许调用线程继续异步执行。
  1. 返回类型
  • Task.WaitAll:没有返回值。
  • Task.WhenAll:返回代表所有提供的任务完成的 Task。
  1. 应用场景
  • Task.WaitAll:当您需要阻止直到任务完成时使用,通常在非 UI 或控制台应用程序中。
  • Task.WhenAll:用于异步编程,尤其是在不希望阻塞主线程的 UI 应用程序中。

实际用例

  1. 何时使用 Task.WaitAll
  • 在控制台应用程序中,您需要确保某些任务在继续之前已经完成。
  • 当您处理不支持异步/等待模式的遗留代码时。
  1. 何时使用 Task.WhenAll
  • 在 UI 应用程序中保持界面响应。
  • 在 Web 应用程序中处理多个异步操作而不阻塞主线程。

结论

Task.WaitAll 和 Task.WhenAll 是 C# 中处理多个任务的必备工具。当您需要阻止调用线程直到任务完成时,请使用 Task.WaitAll;当需要异步等待时,请使用 Task.WhenAll。了解它们的区别和适当的用例可以帮助您编写更高效、响应更快的应用程序。

http://www.lryc.cn/news/399318.html

相关文章:

  • 在Linux系统实现瑞芯微RK3588部署rknntoolkit2进行模型转换
  • 【人工智能】Transformers之Pipeline(概述):30w+大模型极简应用
  • Jenkins中Node节点与构建任务
  • Leetcode3200. 三角形的最大高度
  • docker运行nginx挂载前端html页面步骤
  • kafka部署以及常用命令详细总结
  • 代码随想录算法训练营第29天|LeetCode 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列
  • 代理模式(大话设计模式)C/C++版本
  • 本人学习保存-macOS打开Navicat提示「“Navicat Premium”已损坏,无法打开。 你应该将它移到废纸篓。」的解决方法
  • 《Cross-Image Pixel Contrasting for Semantic Segmentation》论文解读
  • 技术周总结 2024.07.08~07.14(算法,Python,Java,Scala,PHP)
  • UnityECS学习中问题及总结entityQuery.ToComponentDataArray和entityQuery.ToEntityArray区别
  • [python]基于yolov10+gradio目标检测演示系统设计
  • 浏览器开发者视角及CSS表达式选择元素
  • GuLi商城-商品服务-API-品牌管理-统一异常处理
  • VUE+Spring Flux实现SSE长连接
  • C#实现Winform程序右下角弹窗消息提示
  • Java三剑客:封装、继承、多态的魔法世界
  • 0145__Linux的capability
  • # Redis 入门到精通(一)数据类型(4)
  • 西邮计科嵌入式复习
  • Java如何使用 HttpClientUtils 发起 HTTP 请求
  • 无人机的工作原理
  • 敏捷开发笔记(第10章节)--Liskov原则(LSP)
  • 基于SSM的校园一卡通管理系统的设计与实现
  • 新版Android Studio中设置gradle的JDK版本
  • 打造你的智能家居指挥中心:基于STM32的多协议(zigbee、http)网关(附代码示例)
  • 【基于R语言群体遗传学】-16-中性检验Tajima‘s D及连锁不平衡 linkage disequilibrium (LD)
  • 防火墙组网与安全策略实验
  • xmind梳理测试点,根据这些测试点去写测试用例