【.NET Core】异步编程模式
【.NET Core】异步编程模式
文章目录
- 【.NET Core】异步编程模式
- 一、概述
- 二、基于任务的异步模式(TAP)
- 2.1 TAP模式命名、参数和返回类型
- 2.2 TAP初始化异步操
- 2.3 TAP如何编译
- 2.4 手动生成TAP方法
- 2.5 混合方法实现TAP
- 2.6 TAP中Await挂起执行
- 2.7 TAP中使用Yield和ConfigureAwait配置挂起和恢复
- 三、基于事件的异步模式(EAP)
- 四、异步编程模型(APM)
- 4.1 开始异步操作
- 4.2 结束异步操作
一、概述
.NET提供了执行异步操作的三种模式:
- 基于任务的异步模式(TAP),该模式使用单一方法表示异步操作的开始和完成。TAP是在.NET Framework 4 中引入的,这是在.NET中进行异步编程的推荐方法。C#的
async
和await
关键词和Await
运算符为TAP添加了语言支持。 - **基于事件的异步模式(EAP)**是提供异步行为的基于事件的旧模型。这种模式需要后缀为Async的方法,以及一个或多个事件,事件处理程序委托类型和EventArg派生类型。EAP是在.NET Framework2.0中引入的。建议新开发中不再使用这种模式。
- 异步编程模型模式(APM)(也称为IAsyncResult模式),这是使用
IAsyncResult
接口提供异步行为的旧模型。在APM模式下,同步操作需要Begin和End方法。不建议新的开发使用此模式。
二、基于任务的异步模式(TAP)
在.NET中,基于任务的异步模式是建议用于新开发的异步设计模式。它是基于System.Threading.Tasks命名中的Task
和Task<TResult>
类型,这个类型用于表示异步操作。
2.1 TAP模式命名、参数和返回类型
TAP使用单个方法表示异步操作的开始和完成。这与异步编码模型(APM
或IAsyncReult
)模式和基于事件的异步模式(EAP
)形成对比。APM
需要Begin
和End
方法。EAP需要后缀为Async
的方法,以及一个或多个事件,事件处理程序委托类型和EventArg
派生类型。
TAP中的异步方法在返回类型:
System.Threading.Tasks.Task
System.Threading.Tasks.Task<TResult>
具体返回类型取决于相应的同步方法返回的是void还是类型TResult
。
TAP异步方法参数:
TAP方法的参数应与其同步对应方法的参数匹配,并应以相同顺序提供。但是,out
和ref
参数不受此规则的限制,并应完全避免。应该将通过out
或ref
参数返回的所有数据改为作为由TResult
返回的Task<TResult>
的一部分返回,且应使用元组或自定义数据结构来容纳多个值。即使TAP方法的同步对应项没有提供CancellationToken
参数,也应考虑添加此参数。
2.2 TAP初始化异步操
基于TAP的异步方法可以同步完成少量工作,如在返回结果任务之前,验证自变量和启动异步操作。应将同步工作保持最小,以便异步方法可以快速返回。快速返回的原因包括:
- 可以从用户界面线程调用异步方法,因此,所有长期运行的同步工作可能会降低应用程序的响应能力。
- 可以同时启动多个异步方法,因此,在异步方法的同步部分中的任何长时间运行的工作都可以延迟其他异步操作的启动,从而减少并发的优点。
2.3 TAP如何编译
自.NET Framework 4.5起,任何归于async
关键字的方法都被视为异步方法,并且编译器会执行必要的转换,以使用TAP异步实现方法。异步方法应返回System.Treading.Tasks.Task
或System.Threading.Tasks.Task<TResult>
对象。对于后者,函数的主体应该返回TResult
,并且编译器确保此结果是通过生成的任务对象获得。同样,未在方法的主体中处理的任何异常都会被封装处理未输出任务并导致生成的任务结束以TaskStatus.Faulted
状态结束。此规则的异常发生在OperationCanceledException
未得到处理时,在这种情况下生成的任务以TaskStatus.Canceled
状态结束。
2.4 手动生成TAP方法
手动实现TAP模式以更好的控制实现。编译器依赖从System.Threading.Tasks
命名空间公开的公共外围应用和System.Runtime.CompilerServices
命名空间中支持的类型。手动实现TAP
,需要创建一个TaskCompletionSource<TResult>
对象,执行异步操作,并在操作完成时,调用SetResult
、SetException
、SetCanceled
方法或调用这些方法之一的Try
版本。手动实现TAP
方法时,需在所在表示的异步操作完成生成的任务。例如:
public static Task<int> ReadTask(this Stream stream,byte[] buffer,int offset,int count,object state)
{var tcs =new TaskCompletionSource<int>();stream.BeginRead(buffer,offset,count,resp=>{try{tcs.SetResult(stream.EndRead(resp));}catch(Exception ex){tcs.SetException(ex);}},state);return tcs.Task;
}
2.5 混合方法实现TAP
混合方法可以将核心逻辑委托给编译器。如果想验证编译器生成的异步方法之外的参数时,可能需要使用这种混合方法,以便异常可以转义到该方法的直接调用方而不是通过System.Threading.Tasks.Task
对象被公开:
public Task<int> MethodAsync(string input)
{if(input==null) throw new ArgumentNullException("input");return MethodAsyncInternal(input);
}
private async Task<int> MethodAsyncInternal(string input)
{return value;
}
2.6 TAP中Await挂起执行
使用await
关键字开异步等待Task
和Task<TResult>
对象。等待Task
时,await
表达式的返回类型为void
。等待Task<TResult>
时,await
表达式的类型为TResult
。await
表达式必须出现在异步方法的正文内。
实际上,await 功能通过使用延续任务在任务上安装回叫。此回叫在挂起点恢复异步方法。 恢复异步方法时,如果等待的操作已成功完成且为Task<TResult>
,返回的是TResult
。如果等待的Task
或Task<TResult>
以Canceked状态结束。就会抛出OpetationCanceledException
异常。如果等待的Task
或Task<TResult>
以Faulted
状态结束,就会抛出导致它发生故障的异常。一个Task
可能由于多个异常而出错,但只会传播一个异常。不过Task.Exception
属性会返回包含所有错误AggregateException
异常。
调用异步方法时,将同步执行函数的正文,直到遇见尚未完成的可等待实例上的第一个 await 表达式,此时调用返回到调用方。如果异步方法不返回void
,将会返回Task
或Task<TResult>
对象,以表示正在进行的计算。在非void异常方法中,如果遇到return语句或到达方法正文末尾,任务就以RanToCompletion
最终状态完成。如果未经处理的异常导致无法控制异步方法正文,任务就以Faulted
状态结束。如果异常为OperationCanceledException
,任务改为以Canceled
状态结束。
2.7 TAP中使用Yield和ConfigureAwait配置挂起和恢复
使用Task.Yield
方法,将暂停点引入异步方法。
Task.Run(async delegate{int flag=0;do{await Task.Yield();flag++;}while(flag<10000);
});
使用Task.ConfigureAwait
方法,更好地控制异步方法中的暂停和恢复。默认情况下,异步方法挂起时会捕获当前上下文,捕获的上下文用于在恢复时调用异步方法的延续。
三、基于事件的异步模式(EAP)
System.Threading
命名空间提供了创建高性能多线程应用程序所必需的所有工具,但要想有效地使用这些工具,需要有丰富的使用多线程软件工程的经验。对于相对简单的多线程应用程序,BackgroundWorker
组件提供了一个简单的解决方案。对于更复杂的异步应用程序,考虑实现一个符合基于事件的异步模式的类。
基于事件的异步模式具有多线程应用程序的优点,同时隐藏了多线程设计中固有的许多复杂的问题。使用EAP模式的能够:
- “在后台”执行耗时任务(例如下载和数据库操作),但不会中断你的应用程序。
- 同时执行多个操作,每个操作完成时都会接到通知。
- 等待资源变得可用,但不会停止(“阻止”)你的应用程序。
- 使用熟悉的事件和委托模型与挂起的异步操作通信。
支持基于事件的异步模式的类将具有一个或多个命名为 MethodNameAsync
的方法。 这些方法可能会创建同步版本的镜像,这些同步版本会在当前线程上执行相同的操作。 该类还可能具有 MethodNameCompleted
事件,并且可能会具有 MethodNameAsyncCancel
(或只是 CancelAsync)方法。
EAP常用的组件:
许多组件都支持异步执行工作,常用的有SoundPlayer和PictureBox组件,可以“在后台”加载音频和图像,同时主线程继续运行而不中断。
四、异步编程模型(APM)
使用IAsyncResult
设计模式的异步操作时通过名微BeginOperatiobName
和EndOperationName
的两个方法来实现的,这两个方法分别开始和结束异常操作OperationName。例如:FileStream
类提供BeginRead
和EndRead
方法来从文件异步读取字节。
在调用BeginOperationName
后,应用程序可以继续在调用线程上执行指令,同时异步操作在另一个线程上执行。每次调用BeginOperationName
时,应用程序还调用EndOperationName
来获取操作的结果。
4.1 开始异步操作
BeginOperationName
方法开始异步操作OperationName,并返回实现IAsyncResult
接口的对象。IAsyncResult
对象存储有关异步操作的信息。
编号 | 成员 | 描述 |
---|---|---|
1 | AsyncState | 一个特定应用程序的可选对象,其中包含有关异步操作的信息 |
2 | AsyncWaitHandle | 一个WaitHandle,可用来在异步操作完成之前阻止应用程序执行。 |
3 | CompletedSynchronously | 一个指,指示异步操作是否是在用于调用BeginOperationName的线程上完成,而不是在单独的ThreadPool 线程上完成。 |
4 | IsCompleted | 一个值,指示异步操作是否已完成。 |
BeginOperationName
方法采用该方法的同步版本的签名中声明的任何参数(由值传递或由引用传递)。 BeginOperationName
方法签名中不包含任何输出参数。 BeginOperationName
方法签名另外还包括两个其他参数。 第一个参数定义一个 AsyncCallback
委托,此委托引用在异步操作完成时调用的方法。 如果调用方不希望在操作完成后调用方法,它可以指定 null
(在 Visual Basic 中为Nothing
)。 第二个参数是一个用户定义的对象。 此对象可用来向异步操作完成时调用的方法传递应用程序特定的状态信息。 如果 BeginOperationName
方法还采用其他一些操作特定的参数(例如,一个用于存储从文件读取的字节的字节数组),则 AsyncCallback
和应用程序状态对象将是 BeginOperationName
方法签名中的最后两个参数。
BeginOperationName
立即返回对调用线程的控制。 如果 BeginOperationName
方法引发异常,则会在开始异步操作之前引发异常。 如果 BeginOperationName
方法引发异常,则意味着没有调用回调方法。
4.2 结束异步操作
EndOperationName
方法用于结束异步操作OperationName
。EndOperationName
方法的返回值与其同步对应方法的返回值类型相同。并且是特定于异步操作的。
EndOperationName
方法采用该方法同步版本的签名中声明的所有输出参数或引用参数。
如果调用EndOperationName
时IAsyncResult
对象表示的异步操作尚未完成,则EndOperationName
将在异步操作完成之前阻止调用线程。异步操作引发的异常是从EndOperationName
方法引发的。未定义多次使用同一IAsyncResult
调用EndOperationName
方法的效果。
相关文章:
【.NET Core】异步编程模式
【.NET Core】异步编程模式 文章目录 【.NET Core】异步编程模式一、概述二、基于任务的异步模式(TAP)2.1 TAP模式命名、参数和返回类型2.2 TAP初始化异步操2.3 TAP如何编译2.4 手动生成TAP方法2.5 混合方法实现TAP2.6 TAP中Await挂起执行2.7 TAP中使用Y…...
macOS通过外置驱动器备份数据
通过外置驱动器备份数据(谨慎操作) 1.将外置驱动器连接到您的 Mac。驱动器容量应等于或大于您当前的启动磁盘。驱动器还应该是您可以抹掉的。 2.使用 macOS 恢复功能 抹掉外置驱动器,然后将 macOS 安装 到外置驱动器上。确保您选择的外置驱动…...
rtsp解析视频流
这里先说一下 播放rtsp 视频流,尽量让后端转换一下其他格式的流进行播放。因为rtsp的流需要flash支持,现在很多浏览器不支持flash。 先说一下这里我没有用video-player插件,因为它需要用flash ,在一个是我下载flash后,还是无法播放…...
【物联网】手把手完整实现STM32+ESP8266+MQTT+阿里云+APP应用——第3节-云产品流转配置
🌟博主领域:嵌入式领域&人工智能&软件开发 本节目标:本节目标是进行云产品流转配置为后面实际的手机APP的接入做铺垫。云产品流转配置的目的是为了后面能够让后面实际做出来的手机APP可以控制STM32/MCU,STM32/MCU可以将数…...
Spring Cloud Config相关问题及答案(2024)
1、什么是 Spring Cloud Config,它解决了哪些问题? Spring Cloud Config 是一个为微服务架构提供集中化外部配置支持的项目。它是构建在 Spring Cloud 生态系统之上,利用 Spring Boot 的开发便利性,简化了分布式系统中的配置管理…...
【Azure 架构师学习笔记】- Azure Databricks (4) - 使用Azure Key Vault 管理ADB Secret
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (3) - 再次认识DataBricks 前言 Azure Databricks有access token,是具有ADB内部最高权限的token。在云环境中这些高级别权限的sec…...
[每周一更]-(第50期):Go的垃圾回收GC
参考文章: https://juejin.cn/post/7111515970669117447https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-garbage-collector/https://colobu.com/2022/07/16/A-Guide-to-the-Go-Garbage-Collector/https://liangyaopei.github.io/2021/01/02/g…...
【嵌入式学习笔记-01】什么是UC,操作系统历史介绍,计算机系统分层,环境变量(PATH),错误
【嵌入式学习笔记】什么是UC,操作系统历史介绍,计算机系统分层,环境变量(PATH),错误 文章目录 什么是UC?计算机系统分层什么是操作系统? 环境变量什么是环境变量?环境变量的添加&am…...
【动态规划】LeetCode-10. 正则表达式匹配
10. 正则表达式匹配。 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 …...
lenovo联想拯救者8.8英寸掌上游戏机Legion Go 8APU1(83E1)原装出厂Windows11预装系统
链接:https://pan.baidu.com/s/1d586XWXcAWVxlLyV2Oku7Q?pwdd74t 提取码:d74t 系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具:16G或以上的U盘 文件格式:ISO 文件大小:…...
经典目标检测YOLO系列(一)复现YOLOV1(4)VOC2007数据集的读取及预处理
经典目标检测YOLO系列(一)复现YOLOV1(4)VOC2007数据集的读取及预处理 之前,我们依据《YOLO目标检测》(ISBN:9787115627094)一书,提出了新的YOLOV1架构,并解决前向推理过程中的两个问题,继续按照此书进行YOLOV1的复现。 经典目标检…...
Android Studio xml布局代码补全功能失效问题
这里写目录标题 前言:问题描述原因分析:解决方案:1.更新 Android Studio 版本2.原版本解决XML补全失效 小结 前言: 在开发过程中,你可能遇到很多奇奇怪怪的问题。Android Studio 编译器出现问题也是常有的事情&#x…...
算法每日一题:队列中可以看到的人数 | 单调栈
大家好,我是星恒 今天是一道困难题,他的题解比较好理解,但是不好想出来,接下来就让我带大家来捋一捋这道题的思路,以及他有什么特征 题目:leetcode 1944有 n 个人排成一个队列,从左到右 编号为 …...
报表控件Stimulsoft 2023回顾:都做了哪些产品的改变?
在2023年过去一年中,报表控件Stimulsoft 针各类控件都做了重大改变,其中新增了某些产品、同时加强了很多产品的性能和UI设计,更加符合开发者需求,下面就跟随小编一起来回顾,具体都有哪些↓↓↓ Stimulsoft Ultimate &…...
Mybatis缓存实现方式
文章目录 装饰器模式Cache 接口及核心实现Cache 接口装饰器1. BlockingCache2. FifoCache3. LruCache4. SoftCache5. WeakCache 小结 缓存是优化数据库性能的常用手段之一,我们在实践中经常使用的是 Memcached、Redis 等外部缓存组件,很多持久化框架提供…...
C#用StringBuilder高效处理字符串
目录 一、背景 二、使用StringBuilder便捷、高效地操作字符串 三、实例 1.源码 2.生成效果 四、实例中知识点 1.StringBuilder 构造函数 (1)定义 (2)重载 (3)StringBuilder() (4&…...
python开发案例教程-清华大学出版社(张基温)答案(4.2)
目录 练习 4.2 1. 代码分析题 2. 程序设计题 练习 4.2 1. 代码分析题 阅读下面的代码,给出输出结果。 (1) class A:def __init__(self,a,b,c):self.xabca A(3,5,7);b getattr(a,x);setattr(a,x,b3);print(a.x)18 (2&…...
【MATLAB】【数字信号处理】线性卷积和抽样定理
已知有限长序列:xk1,2,1,1,0,-3, hk[1,-1,1] , 计算离散卷积和ykxk*h(k) 。 程序如下: function [t,x] My_conv(x1,x2,t1,t2,dt) %文件名与函数名对应 %自写的卷积函数 x conv(x1,x2)*dt; t0 t1(1) t2(1); L length(x1) length(x2)-2; t t0:dt…...
什么是 MVVM ?
课堂笔记 什么是 MVVM ? MVVM 是一种架构模式,它最初是由微软的两位工程师在 2005 年的时候所提出的。 Model:Model代表的是你的数据View:视图,直接和用户打交道的ViewModel:ViewModel 是 View 和 Model…...
Redis(一)
1、redis Redis是一个完全开源免费的高性能(NOSQL)的key-value数据库。它遵守BSD协议,使用ANSI C语言编写,并支持网络和持久化。Redis拥有极高的性能,每秒可以进行11万次的读取操作和8.1万次的写入操作。它支持丰富的数…...
自动驾驶预测-决策-规划-控制学习(1):自动驾驶框架、硬件、软件概述
文章目录 前言:无人驾驶分级一、不同level的无人驾驶实例分析1.L2级别2.L3级别3.L4级别①如何在减少成本的情况下,实现类似全方位高精度的感知呢?②路侧终归是辅助,主车的智能才是重中之重:融合深度学习 二、无人驾驶的…...
SSM建材商城网站----计算机毕业设计
项目介绍 本项目分为前后台,前台为普通用户登录,后台为管理员登录; 管理员角色包含以下功能: 管理员登录,管理员管理,注册用户管理,新闻公告管理,建材类型管理,配货点管理,建材商品管理,建材订单管理,建材评价管理等功能。 用…...
js逆向第9例:猿人学第2题-js混淆-动态cookie1
题目2:提取全部5页发布日热度的值,计算所有值的加和,并提交答案 (感谢蔡老板为本题提供混淆方案) 既然题目已经给出了cookie问题,那就从cookie入手,控制台找到数据请求地址 可以看到如下加密字符串m类似md5,后面跟着时间戳 m=45cc41dcdb15159ebb50564635f8e362|1704301…...
[论文分享]TimesURL:通用时间序列表示学习的自监督对比学习
论文题目:TimesURL: Self-supervised Contrastive Learning for Universal Time Series Representation Learning 论文地址:https://arxiv.org/abs/2312.15709 代码地址:暂无 摘要 学习适用于各种下游任务的通用时间序列表示具有挑战性&…...
解决sublime中文符号乱码问题
效果图 原来 后来 问题不是出自encode文件编码,而是win10的字体问题。 解决方法 配置: { "font_face":"Microsoft Yahei", "dpi_scale": 1.0 } 参考自 Sublime 输入中文显示方框问号乱码_sublime中文问号-CSDN博…...
厚积薄发11年,鸿蒙究竟有多可怕
12月20日中国工程院等权威单位发布《2023年全球十大工程成就》。本次发布的2023全球十大工程成就包括“鸿蒙操作系统”在内。入围的“全球十大工程成就”,主要指过去五年由世界各国工程科技工作者合作或单独完成且实践验证有效的,并且已经产生全球影响…...
pyDAL一个python的ORM(4) pyDAL查询操作
1 、简单查询 rows db(db.person.dept marketing).select(db.person.id, db.person.name, db.person.dept) rows db(db.person.dept marketing).select() rows db(db.person.dept marketing).select(db.person.ALL) rows db().select(db.person.ALL) / db(db.person).se…...
如何通过Python将各种数据写入到Excel工作表
在数据处理和报告生成等工作中,Excel表格是一种常见且广泛使用的工具。然而,手动将大量数据输入到Excel表格中既费时又容易出错。为了提高效率并减少错误,使用Python编程语言来自动化数据写入Excel表格是一个明智的选择。Python作为一种简单易…...
跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用
配置: 日志库文件github: GitHub - gabime/spdlog: Fast C logging library. 新建vendor文件夹 将下载好的spdlog放入 配置YOTOEngine的附加包含目录: 配置Sandbox的附加包含目录: 包装spdlog: 在YOTO文件夹下创建…...
Ubuntu20.04 上启用 VCAN 用作本地调试
目录 一、启用本机的 VCAN 编辑 1.1 加载本机的 vcan 1.2 添加本机的 vcan0 1.3 查看添加的 vcan0 1.4 开启本机的 vcan0 1.5 关闭本机的 vcan0 1.6 删除本机的 vcan0 二、测试本机的 VCAN 2.1 CAN 发送数据 代码 2.2 CAN 接收数据 代码 2.3 CMakeLists.…...
wordpress chmod() 函数/友妙招链接怎么弄
今天在Android上测试压缩和解压缩。 获得压缩后的byte[]数组后,直接用 byte[].toString()方法取得字符串。 然后用这个字符串再反向来解压缩,还原数据。却发现还原回来的字符串有误。 String str "这是一个用于测试的字符串";try {/** 压缩*/…...
wordpress开放哪个端口/企业网站
通过抓包来看看ip头部和tcp的头部,到底长什么样子 借助华三HCL模拟器 拓扑图 启动路由器模拟器,记得显示接口名称 在crt中给system-view进入到用户视图,sysname r1,给设备重新命名 给g0/0口上配上ip地址 ip add 192.168.1.1 24(24是掩码&…...
池州做网站/企业员工培训内容及计划
LeetCode 53. 最大子序和 大家好,我叫亓官劼(q guān ji ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请大家支持原…...
wordpress chinese-username插件/广东疫情最新情况
JavaScript基本包装类型,数据类型的方法 学习要点: 1.基本包装类型概述 2.Boolean类型 3.Number类型 4.String类型 为了便于操作基本类型值,ECMAScript提供了3个特殊的引用类型:Boolean、Number和String。这些类型与其他引用类型相…...
wp网站怎么用插件做html网页/搜索关键词排名工具
直接把下面代码复制到你要填写的url地址 <?php //定义常量token define(TOKEN,weixin); //检查标签function checkSignature(){//先获取到这三个参数$signature $_GET[signature]; $nonce $_GET[nonce]; $timestamp $_GET[timestamp]; //把这三个参数存到一个数组里面…...
网站目录结构说明/qq引流推广平台
一 下载验证文件 为了搭建课程环境,首先需要RHCI foundation 和 课程 foundation ,文件 如下:The current list of files for the foundation layer:* RHCIfoundation-RHEL71-*.icmf (manifest file)* rhel-server-7.1-x86…...