同步与异步:.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.mzph.cn/news/869479.shtml

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

相关文章

C++ 字符串哈希(hush)讲解

文章目录 什么是哈希(hash)哈希原理实现过程其他练习 什么是哈希(hash) 哈希,又称 hash,它是密码学的基础,理解哈希是理解数字签名和加密通信等技术的必要前提。 在 C 中,哈希通常…

Centos搭建FTP

FTP搭建 安装vsftpd #安装vsftpd yum install vsftpd -y systemctl start vsftpd systemctl enable vsftpd systemctl restart vsftpd创建测试用户 #创建测试用户 useradd -d /home/ftptest -g ftp -s /sbin/false ftptest passwd ftptest #admin12#$.. echo "/sbin/fa…

【单片机毕业设计选题24054】-基于STM32的水质检测系统

系统功能: 主要功能模块原理图: 电源时钟烧录接口: 单片机和按键输入电路: 传感器采集电路: 资料获取地址 系统主要功能模块代码 初始化代码: /* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration-----------------------------------------------…

SpringSecurity(Authorization Events)

Authorization Events 对于每个被拒绝的授权,都会激发一个 AuthorizationDeniedEvent。此外,还可以为授予的授权激发 AuthorizationGrantedEvent。 若要侦听这些事件,必须首先发布 AuthorizationEventPublisher。 Spring Security 的 Spri…

编译Linux内核, 制作迷你系统并在虚拟机里运行(2)

编译制作环境:ubuntu20.0.4 一,参考文档 Linux 系统裁剪--制作一个最小化的Linux iso镜像 https://blog.csdn.net/alfiy/article/details/122568957 按照上述文档的步骤,制作的iso启动不了,经过多次尝试,发现生成的…

【Go - 常见的5类函数用法】

函数 函数通过func关键字定义,后跟函数名、参数列表、返回类型。语法如下: func functionName(parameters) returnType {// 函数体 }示例 func add(x int, y int) int {return x y }func swap(x, y string) (string, string) {return y, x }变参函数…

电脑虚拟摄像头怎么使用?电脑摄像头可以被虚拟摄像头替代吗?8款推荐!

在数字化日益普及的今天,视频通话和在线会议已成为我们生活和工作中不可或缺的一部分。然而,当我们的电脑没有配备摄像头,或摄像头出现故障时,我们可能会面临一些不便。这时,电脑虚拟摄像头便成为了一个实用的解决方案…

C# 策略模式(Strategy Pattern)

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。 // 策略接口 public interface IStrategy { void Execute(); } // 具体策略A public class ConcreteStrategyA : IStra…

前端面试题37(js递归)

在JavaScript中,递归是一种编程技术,它允许函数调用自身来解决问题。这种方法通常用于处理分治策略的算法,比如遍历树形结构、计算阶乘、 Fibonacci数列等。下面通过几个示例来说明如何使用递归。 1. 计算阶乘 阶乘是一个经典的递归示例&am…

[激光原理与应用-102]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 6 - 激光焊接系统的组成

目录 一、激光焊接系统的组成概述 1.1、核心部件 1.2、焊接执行部件 1.3、辅助系统 1.4、控制系统 1.5、其他辅助设备 二、激光器 2.1 按出光类型分 1. 脉冲激光器 2. 连续激光器 3. 准连续激光器(QCW) 4. 其他常见激光器 5. 应用领域 2.2…

SDK游戏盾、高防IP和高防CDN有什么区别

SDK 游戏盾、高防 IP 和高防 CDN 主要有以下区别: SDK 游戏盾: • 原理:通常需要集成到游戏应用程序中,通过在游戏客户端和服务器之间建立加密通道和智能调度,实现对游戏的防护。 • 特点:能更深入地与游…

C 语言中如何进行冒泡排序?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 📙C 语言百万年薪修炼课程 通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代,看过的人都说好。 文章目…

JVM内存泄露的ThreadLocal详解

目录 一、为什么要有ThreadLocal 二、ThreadLocal的使用 三、实现解析 实现分析 具体实现 Hash冲突的解决 开放定址法 链地址法 再哈希法 建立公共溢出区 四、引发的内存泄漏分析 内存泄漏的现象 分析 总结 错误使用ThreadLocal导致线程不安全 一、为什么要有Thr…

Qt开发 | Qt绘图技术 | 常见图像绘制 | Qt移动鼠标绘制任意形状 | Qt绘制带三角形箭头的窗口

文章目录 一、基本绘图技术介绍二、常见的18种图形、路径、文字、图片绘制三、Qt移动鼠标绘制任意形状四、Qt绘制带三角形箭头的窗口 一、基本绘图技术介绍 Qt提供了绘图技术,程序员可以在界面上拖动鼠标,或者在代码里指定参数进行绘图。 Qt绘图技术介绍…

如何在 C 语言中实现链表?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 📙C 语言百万年薪修炼课程 通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代,看过的人都说好。 文章目…

vue子组件调用父组件方法

父组件 页面<popoverss ref"pop" :goodspop"goodspop"></popoverss>子组件components: {"popoverss": () > import(../comm/popover.vue)},方法goodspop(e){console.log(e"----")return 9999;},子组件 方法props:[go…

习题练习以

题意&#xff1a;求i&M的popcount的和&#xff0c;i属于0……N 主要思路还是变加为乘。 举个例子N22&#xff0c;即10110 假设M的第3位是1&#xff0c;分析N中&#xff1a; 00110 00111 00100 00101 发现其实等价于 0010 0011 0000 0001 也就是左边第4位和第5…

《AIGC:智能创作时代》:AI创作革命来临,你准备好了吗?

想象一下&#xff0c;你正在欣赏一幅精美的画作&#xff0c;惊叹于其细腻的笔触和独特的构图。然而&#xff0c;当你得知这幅作品是由人工智能创作时&#xff0c;你会作何感想&#xff1f;这不再是科幻小说中的场景&#xff0c;而是我们正在经历的现实。 在这个AI技术飞速发展的…

QListWidget、QTreeWidget、QTableWidget的拖放

QListWidget、QTreeWidget、QTableWidget的拖放实验 QAbstractItemView::DragDropMode 的枚举值 QAbstractItemView::NoDragDrop0组件不支持拖放操作QAbstractItemView::DragOnly1组件只支持拖动操作QAbstractItemView::DropOnly 2组件只支持放置操作QAbstractItemView::DragDr…

AI 图像处理 --CodeFormer 简介

CodeFormer是一款基于深度学习技术&#xff0c;特别是利用自动编码器和VQGAN&#xff08;Vector Quantised Generative Adversarial Network&#xff09;进行人脸修复和视频增强的强大人工智能工具。它通过高分辨率重建和细节修复&#xff0c;显著提升了图像和视频的质量和视觉…