windows C#-异步编程概述(三)

 任务组合

除了吐司之外,您同时准备好了早餐的所有东西。制作吐司是异步操作(烤面包)和同步操作(添加黄油和果酱)的组合。更新此代码说明了一个重要概念:

异步操作的组合,然后是同步工作,这是异步操作。换句话说,如果操作的任何部分是异步的,则整个操作都是异步的。

上述代码向您展示了您可以使用 Task 或 Task<TResult> 对象来保存正在运行的任务。在使用其结果之前,您需要等待每个任务。下一步是创建表示其他工作组合的方法。在提供早餐之前,您需要等待表示在添加黄油和果酱之前烤面包的任务。您可以使用以下代码表示该工作:

static async Task<Toast> MakeToastWithButterAndJamAsync(int number)
{var toast = await ToastBreadAsync(number);ApplyButter(toast);ApplyJam(toast);return toast;
}

上述方法的签名中有 async 修饰符。这向编译器发出信号,表示此方法包含一个 await 语句;它包含异步操作。此方法表示烤面包,然后添加黄油和果酱的任务。此方法返回一个 Task<TResult>,表示这三个操作的组合。主要代码块现在变为:

static async Task Main(string[] args)
{Coffee cup = PourCoffee();Console.WriteLine("coffee is ready");var eggsTask = FryEggsAsync(2);var baconTask = FryBaconAsync(3);var toastTask = MakeToastWithButterAndJamAsync(2);var eggs = await eggsTask;Console.WriteLine("eggs are ready");var bacon = await baconTask;Console.WriteLine("bacon is ready");var toast = await toastTask;Console.WriteLine("toast is ready");Juice oj = PourOJ();Console.WriteLine("oj is ready");Console.WriteLine("Breakfast is ready!");
}

先前的更改说明了使用异步代码的重要技巧。通过将操作分离到返回任务的新方法中,可以编写任务。您可以选择何时等待该任务。您可以同时启动其他任务。

异步异常

到目前为止,您已经隐式假设所有这些任务都已成功完成。异步方法会引发异常,就像它们的同步对应方法一样。对异常和错误处理的异步支持与一般异步支持的目标相同:您应该编写像一系列同步语句一样读取的代码。任务在无法成功完成时会引发异常。客户端代码可以在等待启动的任务时捕获这些异常。例如,假设烤面包机在烤面包时着火。您可以通过修改 ToastBreadAsync 方法来模拟这种情况,以匹配以下代码:

private static async Task<Toast> ToastBreadAsync(int slices)
{for (int slice = 0; slice < slices; slice++){Console.WriteLine("Putting a slice of bread in the toaster");}Console.WriteLine("Start toasting...");await Task.Delay(2000);Console.WriteLine("Fire! Toast is ruined!");throw new InvalidOperationException("The toaster is on fire");await Task.Delay(1000);Console.WriteLine("Remove toast from toaster");return new Toast();
}

编译上述代码时,您会收到有关无法访问代码的警告。这是故意的,因为一旦烤面包机着火,操作将无法正常进行。

进行这些更改后运行应用程序,您将输出类似于以下文本的内容:

Pouring coffee
Coffee is ready
Warming the egg pan...
putting 3 slices of bacon in the pan
Cooking first side of bacon...
Putting a slice of bread in the toaster
Putting a slice of bread in the toaster
Start toasting...
Fire! Toast is ruined!
Flipping a slice of bacon
Flipping a slice of bacon
Flipping a slice of bacon
Cooking the second side of bacon...
Cracking 2 eggs
Cooking the eggs ...
Put bacon on plate
Put eggs on plate
Eggs are ready
Bacon is ready
Unhandled exception. System.InvalidOperationException: The toaster is on fireat AsyncBreakfast.Program.ToastBreadAsync(Int32 slices) in Program.cs:line 65at AsyncBreakfast.Program.MakeToastWithButterAndJamAsync(Int32 number) in Program.cs:line 36at AsyncBreakfast.Program.Main(String[] args) in Program.cs:line 24at AsyncBreakfast.Program.<Main>(String[] args)

您会注意到,在烤面包机着火和观察到异常之间,有相当多的任务已经完成。当异步运行的任务抛出异常时,该任务就会出错。Task 对象保存在 Task.Exception 属性中抛出的异常。出错的任务在等待时会抛出异常。

需要了解两个重要的机制:异常如何存储在出错的任务中,以及当代码等待出错的任务时如何解包并重新抛出异常。

当异步运行的代码抛出异常时,该异常会存储在 Task 中。Task.Exception 属性是 System.AggregateException,因为在异步工作期间可能会抛出多个异常。任何抛出的异常都会添加到 AggregateException.InnerExceptions 集合中。如果该 Exception 属性为 null,则会创建一个新的 AggregateException,并且抛出的异常是集合中的第一个项目。

出错任务最常见的情况是 Exception 属性只包含一个异常。当代码等待出错的任务时,会重新抛出 AggregateException.InnerExceptions 集合中的第一个异常。这就是为什么此示例的输出显示 InvalidOperationException 而不是 AggregateException。提取第一个内部异常使使用异步方法与使用同步方法尽可能相似。当您的场景可能生成多个异常时,您可以在代码中检查 Exception 属性。

我们建议任何参数验证异常都从任务返回方法中同步出现。

继续之前,请在 ToastBreadAsync 方法中注释掉这两行,否则就再引发另一场灾难:

Console.WriteLine("Fire! Toast is ruined!");
throw new InvalidOperationException("The toaster is on fire");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19431.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础(二十一)——认识系统服务(daemons)

认识系统服务 &#xff08; daemons&#xff09; 1.daemon 与服务 &#xff08; service&#xff09;2. systemd3. systemctl4. systemctl 配置文件 1.daemon 与服务 &#xff08; service&#xff09; 在 Linux 和类 Unix 系统中&#xff0c;daemon&#xff08;守护进程&…

QT QChart+Eigen库绘制线性回归散点图

QChart+Eigen库绘制线性回归散点图 老套路,一图胜千言 项目结构 代码 mainwindow.h #ifndef MAINWINDOW_H #

uniapp开发微信小程序笔记4-自定义组件

前言&#xff1a;本文重点记录的是uniapp如何封装一个自定义组件&#xff0c;以swiper组件为例。 一、创建组件目录 官方文档中的easycom组件规范中可以看到这样一句话&#xff1a; 只要组件安装在项目的components目录下或uni_modules目录下&#xff0c;并符合components/组…

(三)反向传播 Backpropagation

文章目录 反向传播Backpropagation&#xff08;1&#xff09;Chain Rule&#xff08;2&#xff09;Forward pass和Backward pass 反向传播Backpropagation 对于计算Gradient Descent这件事情&#xff0c;我们的neural network是有非常非常多的参数&#xff0c;可能有上百万个参…

Dowex 50WX8 ion-exchange resin可以用于去除水中的金属离子(如钠、钾、镁、钙等)和其他杂质,提高水质,11119-67-8

一、基本信息 中文名称&#xff1a;Dowex 50WX8 离子交换树脂 英文名称&#xff1a;Dowex 50WX8 ion-exchange resin CAS号&#xff1a;11119-67-8 供应商&#xff1a;陕西新研博美生物科技 外观&#xff1a;米色至浅棕色或绿棕色粉末/微球状 纯度&#xff1a;≥95% 分子…

国标GB28181视频平台EasyCVR视频融合平台H.265/H.264转码业务流程

在当今数字化、网络化的视频监控领域&#xff0c;大中型项目对于视频监控管理平台的需求日益增长&#xff0c;特别是在跨区域、多设备、高并发的复杂环境中。EasyCVR视频监控汇聚管理平台正是为了满足这些需求而设计的&#xff0c;它不仅提供了全面的管理功能&#xff0c;还支持…

一家餐饮企业,「闯入」AI阵地

作者| 皮爷 出品|产业家 “我们需要用AI来帮助我们门店破除内卷的状态。”一位连锁餐饮品牌告诉产业家&#xff0c;“这也是我们想尽快把AI用起来的原因&#xff0c;看看能不能带来一些帮助。” 这种情况正发生在一众餐饮企业中。 与这种情况对应的一个背景是&#xff0c…

基于YOLOv8深度学习的智慧社区建筑外墙破损(裂缝、露筋、剥落)检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着智慧社区的发展&#xff0c;对建筑结构健康状况的实时监测变得愈发重要。在此背景下&#xff0c;建筑外墙破损&#xff08;如裂缝、露筋和剥落&#xff09;等问题对建筑物整体结构的安全性和耐久性构成了严重威胁&#xff0c;及时、准确地检测这些问题变得尤为关键。传统的…

单片机UART协议相关知识

概念 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发传输器&#xff09; 是一种 异步 串行 全双工 通信协议&#xff0c;用于设备一对一进行数据传输&#xff0c;只需要两根线&#xff08;TX&#xff0c;RX&#xff09;。 异步&…

Python模块、迭代器与正则表达式day10

1、Python模块 1.1模块的简介 在编写代码的时候&#xff0c;创建的.py文件就被称为一个模块 1.2模块的使用 想要在a文件里使用b文件的时候&#xff0c;只要在a文件中使用关键字import导入即可 1.2.2 from ...import...语句 导入模块可以使用import&#xff0c;如果只导入模…

DDD架构设计知道(1)

看过很多人写架构设计的文章&#xff0c;绝大多数都是站在企业的角度谈“术”的层面。而当今的时代社会特别是00后门更多的会站在个人的角度&#xff0c;去看架构设计。个体和超级单体时代也已经来临&#xff0c;很多传统意义上的企业管理模式也在改变。所以如果架构设计面对当…

ubuntu下连接了192.168.1.x和192.168.2.x两个网络段,如何让这个两个网段互相通信?

在 Ubuntu 上连接两个网络段&#xff08;如 个人终端A 192.168.1.10 和 个人终端B 192.168.2.10&#xff09;&#xff0c;需要配置路由和网络转发功能&#xff0c;使这两个网段能够相互通信。以下是实现方法&#xff1a; 步骤 1&#xff1a;确认网络配置 1. 确保 Ubuntu 机器…

Shell脚本5 -- 脚本与用户交互read

声明&#xff1a; 本文的学习内容来源于B站up主“泷羽sec”视频【shell编程&#xff08;4&#xff09;脚本与用户交互以及if条件判断】的公开分享&#xff0c;所有内容仅限于网络安全技术的交流学习&#xff0c;不涉及任何侵犯版权或其他侵权意图。如有任何侵权问题&#xff0c…

mysql5.7主从问题记录

项目运行一段时间后突然打印如下异常信息。 由于现场环境和数据库是客户提供&#xff0c;看异常提示一直以为是代码问题&#xff0c;导致锁表。 通过逐步排查之后发现&#xff0c;是binlog把磁盘占满了&#xff0c;让客户的DBA设置了一下就恢复。 当设置了主从同步之后&…

使用卷积自编码器进行图像重构

1. 自编码器简介 自编码器&#xff08;Autoencoder&#xff09;是一种无监督学习的神经网络模型&#xff0c;旨在学习数据的有效表示。自编码器的主要组成部分包括编码器和解码器&#xff0c;二者共同工作以实现数据的压缩和重构。以下是自编码器的详细介绍&#xff1a; 1.1 …

鸿蒙实战:页面跳转传参

文章目录 1. 实战概述2. 实现步骤2.1 创建鸿蒙项目2.2 编写首页代码2.3 新建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 本次实战&#xff0c;学习如何在HarmonyOS应用中实现页面间参数传递。首先创建项目&#xff0c;编写首页代码&#xff0c;实现按钮跳转至第二个页面并…

恶意代码分析入门--静态分析(chapter1_Lab01-01)

恶意代码分析-工具收集 - 17bdw - 博客园 (cnblogs.com) 实验环境&#xff1a;Lab 1-1 这个实验使用Lab01-01.exe和Lab01-01.dll文件&#xff0c;使用本章描述的工具和技术来获取 关于这些文件的信息。 操作环境 操作场景&#xff1a; windows xp sp3 实验工具&#xff1a; PEi…

【操作系统不挂科】<信号量(9)>选择题(带答案与解析)

前言 大家好吖&#xff0c;欢迎来到 YY 滴操作系统不挂科 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 本博客主要内容&#xff0c;收纳了一部门基本的操作系统题目&#xff0c;供yy应对期中考试复习。大家可以参考 本章为选择题题库&#xff0c;试卷…

服务器数据恢复—raid5阵列故障导致上层系统分区无法识别的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌DL380服务器&#xff0c;服务器中三块SAS硬盘组建了一组raid5阵列。服务器安装Windows Server操作系统&#xff0c;划分了3个分区&#xff0c;D分区存放数据库&#xff0c;E分区存放数据库备份。 服务器故障&#xff1a; RAID5阵列中有一…

【ARM】MDK在debug模式下的Registers窗口包含哪些内容

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决客户对于Debug模式下&#xff0c;对于Registers窗口包含的内容了解。 2、 问题场景 Registers窗口是在进入到debug模式下后&#xff0c;就会出现一个窗口。窗口中包含了很多寄存器信息。但是对于具体内容不了解…