【微软技术栈】与其他异步模式和类型互操作
本文内容
- 任务和异步编程模型 (APM)
- 任务和基于事件的异步模式 (EAP)
- 任务和等待句柄
.NET 中异步模式的简短历史记录:
- .NET Framework 1.0 引进了 IAsyncResult 模式,也称为异步编程模型 (APM) 或
Begin/End
模式。 - .NET Framework 2.0 增加了基于事件的异步模式 (EAP)。
- .NET Framework 4 引进了基于任务的异步模式 (TAP),它取代了 APM 和 EAP,并能够轻松构建从早期模式中迁移的例程。
1、任务和异步编程模型 (APM)
1.1 从 APM 到 TAP
因为异步编程模型 (APM) 模式的结构合理,而且能够轻松生成包装,将 APM 实现公开为 TAP 实现。 .NET Framework 4 及更高版本包含采用 FromAsync 方法重载形式的帮助器例程来实现这种转换。
请考虑 Stream 类及其 BeginRead 和 EndRead 方法,它们代表与同步 Read 方法对应的 APM:
public int Read(byte[] buffer, int offset, int count)
public IAsyncResult BeginRead(byte[] buffer, int offset,int count, AsyncCallback callback,object state)
public int EndRead(IAsyncResult asyncResult)
可以使用 TaskFactory<TResult>.FromAsync 方法来实现此操作的 TAP 包装,如下所示:
public static Task<int> ReadAsync(this Stream stream,byte[] buffer, int offset,int count)
{if (stream == null)throw new ArgumentNullException("stream");return Task<int>.Factory.FromAsync(stream.BeginRead,stream.EndRead, buffer,offset, count, null);
}
此实现类似于以下内容:
public static Task<int> ReadAsync(this Stream stream,byte [] buffer, int offset,int count){if (stream == null)throw new ArgumentNullException("stream");var tcs = new TaskCompletionSource<int>();stream.BeginRead(buffer, offset, count, iar =>{try {tcs.TrySetResult(stream.EndRead(iar));}catch(OperationCanceledException) {tcs.TrySetCanceled();}catch(Exception exc) {tcs.TrySetException(exc);}}, null);return tcs.Task;
}
1.2 从 TAP 到 APM
如果现有的基础结构需要 APM 模式,则还需要采用 TAP 实现并在需要 APM 实现的地方使用它。 由于任务可以组合,并且 Task 类实现 IAsyncResult,你可以使用一个简单的 helper 函数执行此操作。 以下代码使用 Task<TResult> 类的扩展,但可以对非泛型任务使用几乎相同的函数。
public static IAsyncResult AsApm<T>(this Task<T> task,AsyncCallback callback,object state)
{if (task == null)throw new ArgumentNullException("task");var tcs = new TaskCompletionSource<T>(state);task.ContinueWith(t =>{if (t.IsFaulted)tcs.TrySetException(t.Exception.InnerExceptions);else if (t.IsCanceled)tcs.TrySetCanceled();elsetcs.TrySetResult(t.Result);if (callback != null)callback(tcs.Task);}, TaskScheduler.Default);return tcs.Task;
}
现在,请考虑具有以下 TAP 实现的用例:
public static Task<String> DownloadStringAsync(Uri url)
并且想要提供此 APM 实现:
public IAsyncResult BeginDownloadString(Uri url,AsyncCallback callback,object state)
public string EndDownloadString(IAsyncResult asyncResult)
以下示例演示了一种向 APM 迁移的方法:
public IAsyncResult BeginDownloadString(Uri url,AsyncCallback callback,object state)
{return DownloadStringAsync(url).AsApm(callback, state);
}public string EndDownloadString(IAsyncResult asyncResult)
{return ((Task<string>)asyncResult).Result;
}
2、任务和等待句柄
2.1 从等待句柄到 TAP
虽然等待句柄不能实现异步模式,但高级开发人员可以在设置等待句柄时使用 WaitHandle 类和 ThreadPool.RegisterWaitForSingleObject 方法实现异步通知。 可以包装 RegisterWaitForSingleObject 方法以在等待句柄中启用针对任何同步等待的基于任务的替代方法:
public static Task WaitOneAsync(this WaitHandle waitHandle)
{if (waitHandle == null)throw new ArgumentNullException("waitHandle");var tcs = new TaskCompletionSource<bool>();var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle,delegate { tcs.TrySetResult(true); }, null, -1, true);var t = tcs.Task;t.ContinueWith( (antecedent) => rwh.Unregister(null));return t;
}
使用此方法,可以在异步方法中使用现有 WaitHandle 实现。 例如,若要限制在任何特定时间执行的异步操作数,可以利用信号灯(System.Threading.SemaphoreSlim 对象)。 可以将并发运行的操作数目限制到 N,方法为:初始化到 N 的信号量的数目、在想要执行操作时等待信号量,并在完成操作时释放信号量 :
static int N = 3;static SemaphoreSlim m_throttle = new SemaphoreSlim(N, N);static async Task DoOperation()
{await m_throttle.WaitAsync();// do workm_throttle.Release();
}
还可以构建不依赖等待句柄就完全可以处理任务的异步信号量。 若要执行此操作,可以使用 使用基于任务的异步模式 中所述的用于在 Task。
2.2 从 TAP 到等待句柄
正如前面所述, Task 类实现 IAsyncResult,且该实现公开 IAsyncResult.AsyncWaitHandle 属性,该属性会返回在 Task 完成时设置的等待句柄。 可以获得 WaitHandle 的 Task ,如下所示:
WaitHandle wh = ((IAsyncResult)task).AsyncWaitHandle;
相关文章:
【微软技术栈】与其他异步模式和类型互操作
本文内容 任务和异步编程模型 (APM)任务和基于事件的异步模式 (EAP)任务和等待句柄 .NET 中异步模式的简短历史记录: .NET Framework 1.0 引进了 IAsyncResult 模式,也称为异步编程模型 (APM) 或 Begin/End 模式。.NET Framework 2.0 增加了基于事件的…...

计算机毕业设计 基于微信小程序的“共享书角”图书借还管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
腾讯云CVM标准型SA5云服务器AMD EPYC Bergamo处理器
腾讯云服务器标准型SA5实例是最新一代的标准型实例,CPU采用AMD EPYC™ Bergamo全新处理器,采用最新DDR5内存,默认网络优化,最高内网收发能力达4500万pps。腾讯云百科txybk.com分享腾讯云标准型SA5云服务器CPU、内存、网络、性能、…...
网站要怎么进行维护和防御攻击
随着数字经济的不断发展,互联网各业都在稳步发展,但是很多站长搭建网站程序后也不知道怎么去维护网站的稳定和是否有漏洞后门等,为此德迅云安全专门为各大站长研发了网站监测产品 知道网站表现:网站监测可以帮助您了解您的网站的…...
代码随想录二刷 | 哈希表 |四数相加II
代码随想录二刷 | 哈希表 |四数相加II 题目描述解题思路 & 代码实现 题目描述 454.四数相加II 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0…...

Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决
Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决 问题描述: 长按TextField后,显示剪切、复制等选项为英文,如下图所示,这是因为问未设置语言本地化,我们需要进行设置。 首先在pubspec.yaml加入以下依赖…...

如何找出excel中两列数据中不同的值(IF函数的用法)
第一部分,举例: 例1: 如下图所示,A列和B列是需要比较的数据,C列为对比规则:IF(A2B2,"是","否") 示例图 例2:给B列的成绩评等级 C列的规则: IF(B2>85,&qu…...

C# WPF上位机开发(掌握一点c#基础)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 wpf虽然比较简单,但是最好还是要有一点c#的基础比较好。本身wpf有点类似于web开发,前端和html差不多,后端则和j…...

UIkit-UIAlertContent
简单Demo //注意!!!必须放在viewController的viewDidAppear里面,viewDidLoad里面不行 - (void)viewDidAppear:(BOOL)animated {// 创建 UIAlertControllerUIAlertController *alertController [UIAlertController alertControll…...

C语言-内存函数详解
文章目录 1. memcpy使用和模拟实现2. memmove使用和模拟实现3. memset函数的使用4. memcmp函数的使用 1. memcpy使用和模拟实现 返回类型和参数: void * memcpy ( void * destination, const void * source, size_t num );1.函数memcpy从source的位置开始向后复制…...

超越噪音,让音乐重获新生:iZotope RX 10音频降噪修复软件
在音乐制作或者音频处理的过程中,噪音往往是一个让人头痛的问题。无论是环境噪音,还是设备产生的噪音,都会对音频质量产生重大影响。而现在,我们有了iZotope RX 10,这款专业的音频降噪修复软件,可以将你从噪…...

【兔子王赠书第9期】ChatGPT进阶:提示工程入门
文章目录 写在前面ChatGPT推荐图书关键点编辑推荐内容简介推荐理由 粉丝福利写在后面 写在前面 人类一直在寻找、制造并使用工具,以扩展我们的能力,适应我们的环境,甚至超越我们的生物限制。现在,我们正站在一个历史性的分水岭之…...

机器学习基础Matplotlib绘图
一、运行环境 学习工具:jupyter-notebookpython版本:311系统:Win11 二、什么是matplotlib? matplotlib是基于python生态开发的一个可视化绘图库,它的出现让python在数据分析及机器学习方面占了重要的一部分&#…...

【高效开发工具系列】PlantUML入门使用
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【第三节:微信小程序 3、app.js配置】微信小程序入门,以思维导图的方式展开3
目录 提供了2个函数: app.js配置 【第三节:微信小程序 3、app.js配置】微信小程序入门,以思维导图的方式展开3 提供了2个函数: app() getApp() --------------------------- app.js配置 App() 功能 Ap…...
Vue 或者 React 中,什么情况下会用 Es6 的 Class 类
// 问个问题,一般在 Vue 或者 React中 // 在框架具备很多组件通讯技术或者js语法支持的情况下,什么情况下会用 Es6 的 Class类?在Vue或React中,通常会在以下情况下使用ES6的Class类: 复杂组件或模块: 当需要构建较为复…...

【Android】Android Framework系列--Launcher3各启动场景源码分析
Android Framework系列–Launcher3各启动场景源码分析 Launcher3启动场景 Launcher3是Android系统提供的默认桌面应用(Launcher),它的源码路径在“packages/apps/Launcher3/”。 Launcher3的启动场景主要包括: 开机后启动:开机时ÿ…...
【Qt开发流程】之拖放操作1:介绍
描述 Drag and drop 提供了一种简单的可视化机制,用户可以使用它在应用程序之间和应用程序内部传输信息。拖放的功能类似于剪贴板的剪切和粘贴机制。 本文描述了基本的拖放机制,并概述了在自定义控件中启用该机制的方法。Qt的许多控件也支持拖放操作&a…...

招募引流模式是实体门店吸引顾客的一种有效策略
在如今激烈的市场竞争和庞大的客户需求中,应该采取什么样的方式来应对,才能找到自己的一席之地。招募引流模式是实体门店吸引顾客的一种有效策略,通常招募体验官或合作伙伴,让他们协助门店进行推广活动,达到增加客流量…...

macos安装小软件 cmake
一,cmake下载主页 Download CMake 二,下载,解压,配置,编译,安装 0. 假设macos中已经存在了 clang和make工具 1. 通过网页下载最新的稳定版 cmake***.tar.gz 源代码 2. tar zxf cmake***.tar 3. cd cmake***…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...