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

【.NET Core】深入理解异步编程模型(APM)

【.NET Core】深入理解异步编程模型(APM)

文章目录

  • 【.NET Core】深入理解异步编程模型(APM)
    • 一、APM概述
    • 二、IAsyncResult接口
      • 2.1 BeginInvoke
      • 2.2 EndInvoke
      • 2.3 IAsyncResult属性
      • 2.4 IAsyncResult异步演示
    • 三、通过结束异步操作来阻止应用程序执行
    • 四、使用AsyncWaitHandle阻止应用程序的执行
    • 五、轮询异步操作的状态
    • 六、总结

在这里插入图片描述

一、APM概述

APM英文是Asynchronous Programming Model是net 1.0时期就提出的一种异步模式,并基于IAsyncResult接口实现Beginxxx和Endxxx的两个方法来实现的,Beginxxx方法是开始异步操作,Endxxx方法是结束异步操作。

在调用Beginxxx后,应用程序可以继续在调用线程上执行指令,同时异步操作在另一个线程上执行。每次调用Beginxxx时,应用程序还应调用Endxxx来获取操作的结果。

public class Budget
{public delegate string FindBudgetDelegate();public string FindBudget() {Thread.Sleep(20000);return $"2024年财年预算-预算科目编制.";}
}

IAsyncResult实现APM

static void Main(string[] args)
{Budget budget =new Budget();Budget.FindBudgetDelegate findBudgetDelegate  =budget.FindBudget;IAsyncResult asyncResult =   findBudgetDelegate.BeginInvoke(null,null);string response =  findBudgetDelegate.EndInvoke(asyncResult);Console.WriteLine(response);
}

二、IAsyncResult接口

接口IAsyncResult由包含可异步操作的方法的类实现。它是启动操作的方法的返回类型。IAsyncResult当异步操作完成时,对象会传递给委托调用AsyncCallback的方法。使用.NET可以以异步方法调用任何方法。首先,需要定义一个委托,该委托具有与调用的方法相同的签名。公共语言运行时将自动用适当的签名为此委托定义BeginInvokeEndInvoke方法。

2.1 BeginInvoke

BeginInvoke方法启动异步调用。该方法具有与你要异步的方法相同的参数,另加两个可选参数。第一个参数是一个AsyncCallBack委托。此委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象将信息传递到回调方法。BeginInvoke将立即返回,而不会等待异步调用完成。BeginInvoke返回可用于监视异步调用的进度的IAsyncResult

2.2 EndInvoke

EndInvoke方法用于检索异步调用的结果。它可以在调用BeginInvoke之后的任意时间调用。如果异步调用尚未结束,那么EndInvoke将阻止调用线程,直到完成异步调用。EndInvoke的参数包括要异步执行的方法的outref参数。

2.3 IAsyncResult属性

序号属性说明
1AsyncState获取一个用户定义的对象,该对象限定或包含有关异步操作的信息
2AsyncWaitHandle获取用于等待异步操作完成的WaitHandle
3CompletedSynchronously获取一个值,该值指示异步操作是否同步完成
4IsCompleted获取一个值,该值指示异步操作是否完成

2.4 IAsyncResult异步演示

static void Main(string[] args)
{Budget budget =new Budget();Budget.FindBudgetDelegate findBudgetDelegate  =budget.FindBudget;IAsyncResult asyncResult =   findBudgetDelegate.BeginInvoke(new AsyncCallback(FindOneAsyncCallBack),null);Console.WriteLine("BeginInvoke异步开始");Console.WriteLine($"当前主线程{Thread.CurrentThread.Name}");Console.WriteLine($"Main->{asyncResult.AsyncState}");Console.WriteLine("WaitOne");Console.ReadKey();
}static void FindOneAsyncCallBack(IAsyncResult asyncResult) 
{Budget.FindBudgetDelegate budgetDelegate =   ((AsyncResult)asyncResult).AsyncDelegate as Budget.FindBudgetDelegate;Console.WriteLine(budgetDelegate.EndInvoke(asyncResult));Console.WriteLine($"FindOneAsyncCallBack->{asyncResult.AsyncState}");
}

三、通过结束异步操作来阻止应用程序执行

如果应用无法在等待异步操作结果期间继续执行其他工作,必须阻止应用一直到操作完成。可以使用下列方法之一,在应用等待异步操作完成期间阻止应用的主程序:

  • 调用异步操作的EndOperationName方法。
  • 使用异步操作的BeginOperationName方法返回的IAsyncResultAsyncWaitHandle属性。

在异步操作完成前使用EndOperationName方法阻止的应用程序,通常会调用BeginOperationName方法,执行任何不需要等待操作结果也可以执行的工作,然后调用EndOperationName

static void Main(string[] args)
{Budget budget =new Budget();Budget.FindBudgetDelegate findBudgetDelegate  =budget.FindBudget;IAsyncResult asyncResult =   findBudgetDelegate.BeginInvoke(null,null);string response =  findBudgetDelegate.EndInvoke(asyncResult);Console.WriteLine(response);
}

四、使用AsyncWaitHandle阻止应用程序的执行

在异步操作完成前使用一个或多个WaitHandle对象阻止的应用,通常会调用BeginOperationName方法,执行任何不需要等待操作结果也可以执行的工作,并在一个或多个异常操作完成前一直处于阻止状态。可以使用AsyncWaitHandle调用WaitOne方法之一,对单一操作阻止应用。若要在等待一组异步操作完成期间阻止应用,请将关联的AsyncWaitHandle对象存储到数组中,并调用WaitAll方法之一。若要在等待一组异步操作中任一操作完成期间阻止应用。请将关联的AsyncWaitHandle对象存储到数组中,并调用WaitAny方法之一。

static void Main(string[] args)
{Budget budget =new Budget();Budget.FindBudgetDelegate findBudgetDelegate  =budget.FindBudget;IAsyncResult asyncResult =   findBudgetDelegate.BeginInvoke(null,null);// Wait until the operation completesasyncResult.AsyncWaitHandle.WaitOne();string response =  findBudgetDelegate.EndInvoke(asyncResult);Console.WriteLine(response);
}

五、轮询异步操作的状态

如果应用可以在等待异步操作结果期间继续执行其他工作,不得阻止应用一直到操作完成。请使用下列方法之一,在应用等待异步操作完成期间继续执行指令:

  • 使用返回IAsyncResultIsCompleted属性,确定操作是否已完成。这种方法称为"轮询"。
  • 使用AsyncCallBack委托,在单独的线程中处理异步操作结果。

六、总结

使用委托可通过异步方式调用同步方法。 如果同步调用委托,Invoke 方法将在当前线程上直接调用目标方法。 如果调用 BeginInvoke 方法,公共语言运行时 (CLR) 将对请求进行排队并立即返回给调用方。 目标方法将在线程池中的某个线程上异步调用。 提交请求的原始线程可以不受限制地继续与目标方法并行执行。 如果已在对 BeginInvoke 方法的调用中指定回叫方法,则目标方法结束时,将调用回叫方法。 在回叫方法中,EndInvoke 方法将获取返回值和所有输入/输出或仅输出参数。 如果调用 BeginInvoke 时未指定回叫方法,则可能从调用 BeginInvoke 的线程上调用 EndInvoke

相关文章:

【.NET Core】深入理解异步编程模型(APM)

【.NET Core】深入理解异步编程模型(APM) 文章目录 【.NET Core】深入理解异步编程模型(APM)一、APM概述二、IAsyncResult接口2.1 BeginInvoke2.2 EndInvoke2.3 IAsyncResult属性2.4 IAsyncResult异步演示 三、通过结束异步操作来…...

pyqtgraph绘图类

pyqtgraph绘图类 pyqtgraph绘图有四种方法: 方法描述pyqtgraph.plot()创建一个新的QWindow用来绘制数据PlotWidget.plot()在已存在的QWidget上绘制数据PlotItem.plot()在已存在的QWidget上绘制数据GraphicsLayout.addPlot()在网格布局中添加一个绘图 上面四个方法都接收同样…...

C#6-10新增的内容

目录 异常筛选器 属性语法 表达式主体定义 Null 条件运算符 ?. 和 ?[] 使用 $ 的字符串内插 nameof 表达式 元组类型 模糊匹配 本地函数 Expression-bodied 成员 Reference 变量 ?、??和??= .. 模式匹配功能(C# 9) Record init c#8.NET Framework 4.8…...

【立创EDA-PCB设计基础】3.网络表概念解读+板框绘制

前言:本文对网络表概念解读板框绘制(确定PCB板子轮廓) 网络表概念解读 在本专栏的上一篇文章【嘉立创EDA-PCB设计指南】2,将设计的原理图转为了PCB,在PCB界面下出现了所有的封装,以及所有的飞线属性&…...

在Python环境中运行R语言的配环境实用教程

前情提要 在做一些生物信息与医学统计的工作,本来偷懒希望只靠python完成的,结果还是需要用R语言,倒腾了一会儿,调成功了,就记录一下这个过程。 我的环境: win10, pycharm, R-4.3.2 首先,我们…...

2023年总结我所经历的技术大变革

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅…...

基于YOLOv7算法的高精度实时车载摄像头下车辆检测系统(PyTorch+Pyside6+YOLOv7)

摘要:基于YOLOv7算法的高精度实时车载摄像头下车辆检测系统可用于日常生活中检测与定位车辆,此系统可完成对输入图片、视频、文件夹以及摄像头方式的目标检测与识别,同时本系统还支持检测结果可视化与导出。本系统采用YOLOv7目标检测算法来训…...

深度学习(3)--递归神经网络(RNN)和词向量模型Word2Vec

目录 一.递归神经网络基础概念 二.自然语言处理-词向量模型Word2Vec 2.1.词向量模型 2.2.常用模型对比 2.3.负采样方案 2.4.词向量训练过程 一.递归神经网络基础概念 递归神经网络(Recursive Neural Network, RNN)可以解决有时间序列的问题,处理诸如树、图这样…...

【江科大】STM32:中断系统(理论)

文章目录 中断系统为什么要使用中断中断优先级中断嵌套STM32的中断系统如何管理这些中断NVIC的结构![请添加图片描述](https://img-blog.csdnimg.cn/c77b038fd63a4ddfbcd3b86f6dfe596b.png) 优先级窗口看门狗(WWDG):外部中断模块的特性&#…...

JAVA 学习 面试(六)数据类型与方法

数据类型 基本数据类型 为什么float3.4报错 3.4 默认是浮点double类型的,如果赋值给float是向下转型,会出现精度缺失,,需要强制转换 Switch支持的数据类型? byte、short、int、char 、 enum 、 String 基本类型与包…...

Java 一个数组集合List<People> 赋值给另一个数组集合List<NewPeople> ,两个数组集合属性部分一致。

Java 一个数组集合List 赋值给另一个数组集合List ,两个数组集合属性部分一致。 下面是一个Demo, 具体要根据自己的业务调整。 import java.util.ArrayList; import java.util.List;class People {private String name;private int age;private String address;publ…...

基于神经网络的电力系统的负荷预测

一、背景介绍: 电力系统负荷预测是生产部门的重要工作之一,通过准确的负荷预测,可以经济合理地安排机组的启停、减少旋转备用容量、合理安排检修计划、降低发电成本和提高经济效益。负荷预测按预测的时间可以分为长期、中期和短期负荷预测。…...

OpenCV第 1 课 计算机视觉和 OpenCV 介绍

文章目录 第 1 课 计算机视觉和 OpenCV 介绍1.机器是如何“看”的2.机器视觉技术的常见应用3.图像识别介绍4. 图像识别技术的常见应用5.OpenCV 介绍6.图像在计算机中的存储形式 第 1 课 计算机视觉和 OpenCV 介绍 1.机器是如何“看”的 我们人类可以通过眼睛看到五颜六色的世界…...

C++面试:stl的栈和队列介绍

目录 栈 栈(stack)的声明: push(): 将元素推入栈顶 pop(): 弹出栈顶元素 top(): 访问栈顶元素,但不弹出 empty(): 检查栈是否为空 size(): 返回栈中元素的数量 …...

从0开始学习C++ 第十二课:指针强化

第十二课:指针强化 学习目标: 理解常量指针与指针常量的区别。学习如何使用函数指针。掌握指针与数组的高级使用技巧。 学习内容: 常量指针与指针常量 概念: 常量指针是一个指向常量的指针,这意味着不能通过这个指针…...

mongodb和python交互

1. mongdb和python交互的模块 pymongo 提供了mongdb和python交互的所有方法 安装方式: pip install pymongo 2. 使用pymongo 2.1 导入pymongo并选择要操作的集合 数据库和集合能够自动创建 2.1.1 无需权限认证的方式创建连接对象以及集合操作对象 from pymongo import Mong…...

力扣279. 完全平方数

动态规划 思路&#xff1a; 假设 dp[i] 为最少组成数 i 的平方数个数&#xff1b;则其上一个状态为 dp[i - j^2] 1&#xff0c;1 为 j^2&#xff1a; 即 i 的最少完全平方数 i - j^2 的最少完全平方数 1&#xff0c;其中 j^2 < i 为最接近 i 的平方数&#xff1b;初始值…...

【C++】list容器功能模拟实现

介绍 上一次介绍了list队容器的迭代器模拟&#xff0c;这次模拟实现list的简单功能&#xff0c;尤其要注意构造函数、析构函数、以及赋值运算符重载的实现。 list容器需要接纳所有类型的数据&#xff0c;因此&#xff0c;结构设置与迭代器设置同理&#xff0c;需要引入结点&…...

linux 安装ffmpeg

一、下载 ffmpeg-4.3.1 下载地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1xbkpHDfIWSCbHFGJJHSQcA 提取码&#xff1a;3eil 二、上传到服务器root目录下 三、给ffmpeg-4.3.1 读写权限 chmod -R 777 /root/ffmpeg-4.3.1 四、创建软连接 1.进入/bin 目录 2.…...

激光雷达行业梳理2-产业链、公司、未来展望

四、产业链及竞争格局 激光雷达产业链可以分为上游&#xff08;光学和电子元器件&#xff09;、中游&#xff08;集成激光雷达&#xff09;、下游&#xff08;不同应用场景&#xff09;。其中 上游即激光发射、激光接收、扫描系统和信息处理四大部分&#xff0c;主要包括激光器…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...

Docker、Wsl 打包迁移环境

电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本&#xff1a; 2.2.4.0 内核版本&#xff1a; 5.15.153.1-2 WSLg 版本&#xff1a; 1.0.61 MSRDC 版本&#xff1a; 1.2.5326 Direct3D 版本&#xff1a; 1.611.1-81528511 DXCore 版本&#xff1a; 10.0.2609…...

更新 Docker 容器中的某一个文件

&#x1f504; 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法&#xff0c;适用于不同场景。 ✅ 方法一&#xff1a;使用 docker cp 拷贝文件到容器中&#xff08;最简单&#xff09; &#x1f9f0; 命令格式&#xff1a; docker cp <…...