当前位置: 首页 > 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;主要包括激光器…...

Java 设计者模式以及与Spring关系(四) 代理模式

目录 简介: 23设计者模式以及重点模式 代理模式&#xff08;Proxy Pattern&#xff09; 静态代理示例 spring中应用 动态代理 1.基于JDK的动态代理 target.getClass().getInterfaces()作用 内名内部类写法(更简洁&#xff0c;但不推荐) 2.基于CGLIB实现 spring中应用 …...

PHP编程实践:实际商品价格数据采集

引言 在电子商务领域&#xff0c;对商品价格进行数据采集和对比是一项常见的需求。本文将介绍如何使用PHP编程语言实现对1688和淘宝商品价格数据的采集和对比&#xff0c;帮助读者了解实际的编程实践过程。 一、数据采集原理 数据采集是指从互联网上获取数据的过程&#xff…...

有效防范网络风险的关键措施

在数字化时代&#xff0c;企业面临着日益复杂和频繁的网络风险。提高员工的网络安全意识是防范网络威胁的关键一步。本文将探讨企业在提升网络安全意识方面可以采取的措施&#xff0c;以有效预防潜在的网络风险。 1. 开展网络安全培训&#xff1a;企业应定期组织网络安全培训&…...

Spring Boot整合webservice

Spring Boot整合webservice 前言1.整合依赖2.建立暴露接口2.实现类 3.发布服务4.查看打完收工&#xff01; 前言 工作中遇到的问题&#xff0c;由于下游系统属于第三方系统&#xff0c;使用的是soap webservice&#xff0c;同时也在开发&#xff0c;虽然也发布了一套webservic…...

Qt拖拽事件简单实现

1.相关说明 重写resizeEvent(这个按需重写)、dragEnterEvent(拖拽事件函数)、dropEvent(放下事件函数)&#xff0c;可以将本地图片拖拽到label标签中 2.相关界面 3.相关代码 #include "widget.h" #include "ui_widget.h" #include <QDragEnterEvent>…...

上门回收小程序,打造回收新模式

近年来&#xff0c;我国一直秉持着环保绿色的发展理念&#xff0c;为了减少资源浪费&#xff0c;旧物回收成为了人们处理废弃物品的方式。目前&#xff0c;我国回收市场规模大约能达到3.58亿元&#xff0c;在我国经济的稳定增长和环保意识的提高下&#xff0c;回收市场规模还将…...

unity项目《样板间展示》开发:火焰和UI设计

第二章&#xff1a;火焰和UI设计 前言一、火焰模型管理灶台火焰壁炉火焰 二、电视机播放三、UI设计结语 前言 这次带大家从0到1做一个unity项目&#xff1a;《样板间展示》。 顾名思义&#xff0c;项目内容是展示样板间&#xff0c;即玩家可以与房间中的物体、家具进行交互。 至…...

即插即用篇 | UniRepLKNet:用于音频、视频、点云、时间序列和图像识别的通用感知大卷积神经网络 | DRepConv

大卷积神经网络(ConvNets)近来受到了广泛研究关注,但存在两个未解决且需要进一步研究的关键问题。1)现有大卷积神经网络的架构主要遵循传统ConvNets或变压器的设计原则,而针对大卷积神经网络的架构设计仍未得到解决。2)随着变压器在多个领域的主导地位,有待研究ConvNets…...

MPU6050传感器—姿态检测

本节主要介绍以下内容&#xff1a; 姿态检测的基本概念 姿态传感器的工作原理及参数 MPU6050传感器介绍 实验&#xff1a;获取MPU6050原始数据 实验&#xff1a;移植官方DMP例程 一、姿态检测基本概念 1.1 姿态 在飞行器中&#xff0c;飞机姿态是非常重要的参数&#x…...

PaddleOCR封装,在线服务化部署实战(python部署,超新手教程)

OCR&#xff0c;即光学字符识别&#xff08;Optical Character Recognition&#xff09;&#xff0c;是一种将图像中的文字转换为机器编码文字的技术。这种技术可以识别和转换各种来源的文本&#xff0c;包括扫描文档、照片中的文字、手写笔记等。光学字符识别&#xff08;OCR&…...