如何在 .NET Core 中轻松实现异步编程并提升性能
目录
初识异步编程
与多线程关系
异步编程操作
初识异步编程
异步编程:是指在执行某些任务时程序可以在等待某个操作完成的过程中继续执行其他任务,而不是阻塞当前线程,这在处理I/O密集型操作(如文件读取、数据库查询、网络请求等)时尤为重要,能够显著提高应用程序的性能和响应能力。
在.net core中异步编程主要通过async和await关键字来实现,结合Task类进行异步操作的管理:
async:标记方法为异步方法使其能够包含await表达式
await:在异步方法中用于等待一个异步操作完成,允许方法在等待期间继续执行其他代码而不会阻塞线程
异步方法通常返回Task或Task<T> 类型:
Task:表示一个没有返回值的异步操作
Task<T>:表示一个带返回值的异步操作,其中T是返回值的类型
作用意义:在进行项目开发的时候通常都会遇到异步编程的使用方式,具备的意义如下:
1)提高应用程序响应性:异步编程可以使得应用程序在等待长时间操作(例如网络请求或文件读写)时继续处理其他任务而不会卡住主线程,比如在桌面应用或Web应用中用户界面不会因等待数据加载而变得无响应
2)提升性能:传统的同步编程会阻塞线程直到操作完成,这可能导致线程资源的浪费,特别是在高并发场景下异步编程允许线程释放去处理其他任务,避免了线程饥饿问题,最大化利用CPU资源特别是在I/O密集型操作时
3)节省资源:异步操作不需要为每个操作分配新的线程,因此能够节省系统资源,在高并发情况下异步编程可以显著减少上下文切换开销
4)适用于I/O密集型应用:异步编程特别适用于那些需要大量I/O操作的应用,例如网络请求、磁盘读取、数据库查询等。通过异步操作可以避免长时间等待I/O操作而导致的性能瓶颈
接下来我们通过异步方法从指定的URL路径上下载网页内容,将网页内容保存到本地文件并输出下载的内容的字节数,代码结果如下所示:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;namespace Program
{class Program{static async Task Main(string[] args){int len = await DownloadHtmlAsync("https://www.baidu.com", @"d:\test\1.txt");Console.WriteLine($"Downloaded {len} bytes.");}static async Task<int> DownloadHtmlAsync(string url, string filename){using (HttpClient client = new HttpClient()){string html = await client.GetStringAsync(url);await File.WriteAllTextAsync(filename, html);return html.Length;}}}
}
与多线程关系
异步编程并不等于多线程,这是两个概念,异步方法的代码并不会自动在新线程中执行,除非把代码放到新线程中执行,以下做一个简单的演示:
使用异步方法来执行长时间运行的计算,通过Thread.CurrentThread.ManagedThreadId输出当前执行线程的ID,可以看到异步方法和线程调度的关系如下,这里我们通过计算5000*5000的情况避免执行太快:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;namespace Program
{class Program{static async Task Main(string[] args){Console.WriteLine("之前:" + Thread.CurrentThread.ManagedThreadId);double r = await CalcAsync(5000);Console.WriteLine("之后:" + Thread.CurrentThread.ManagedThreadId);}static async Task<double> CalcAsync(int n){Console.WriteLine("CalcAsync" + Thread.CurrentThread.ManagedThreadId);double result = 0;Random rand = new Random();for (int i = 1; i <= n*n; i++){result += rand.NextDouble();}return result;}}
}
那么如何在新的线程中执行异步方法呢?这里我们必须手动将异步方法放到新的线程中,这里我们只需要将要执行的代码以委托的形式传递给Task.Run(),这样就会从线程池中取出一个线程来执行我们的委托,如下可以看到我们的线程已经发送了变化:
如果一个异步方法只是对别的异步方法调用转发,并没有太多复杂的逻辑,那么就可以去掉异步关键字直接返回Task,如下所示:
对于多线程来讲,在await调用的等待期间.net会把当前的线程返回给线程池,等异步方法调用执行完毕之后,框架会从线程池再取出一个线程执行后续代码,怎么理解?比如说你进入一家餐馆服务器给你递上一个菜单,在等待你选菜的时候服务你的服务员可能会继续服务别人,当你点餐完毕提交给服务员之后,服务你的服务员可能就不是刚刚服务你的人了,就是这么个意思,当然如果异步等待时间极短,线程可能就不会发送变化:
尽管异步编程和多线程都涉及到并发执行任务,但它们的工作原理和适用场景有所不同,可以把它们看作是两个不同的工具用于解决不同类型的并发问题:
异步编程:通过非阻塞的方式执行操作,适用于 I/O 密集型任务,能够节省线程资源提高应用的响应性。
多线程:通过并行执行任务来提高CPU密集型任务的性能,但线程管理复杂可能带来上下文切换和同步问题。
异步编程与多线程的结合:异步编程通过减少阻塞来提高效率而多线程通过并行执行来加速计算密集型任务,在某些情况下它们可以结合使用:例如异步任务通过线程池线程执行,充分利用多核处理器的计算能力。
异步编程操作
异步等待:如果想在异步方法中暂停一段时间的话,这里可以使用 await Task.Delay()的方式,例如下载一个网址然后等待3秒再下载另一个,注意这里是不能使用Thread.Sleep()方法的,该方法是阻塞线程用的,异步编程并不适用,这里我们演示一下异步等待的效果,如下所示:
class Program
{static async Task Main(string[] args){var input = Console.ReadLine();Console.WriteLine(input);await Task.Delay(3000);Console.WriteLine(input+".net core");}
}
异步取消:在异步编程中CancellationToken是用于取消异步操作的一种机制,它提供了一种优雅的方式来中止正在进行的操作,当用户操作可能会长时间运行时,例如下载文件、访问数据库、调用远程API等,CancellationToken用于支持任务的取消操作,示例如下:
class Program
{static async Task Main(string[] args){CancellationTokenSource cts = new CancellationTokenSource();cts.CancelAfter(3000);CancellationToken cToken = cts.Token;await Download1Async("https://www.baidu.com", 100, cToken);}static async Task Download1Async(string url, int n, CancellationToken token){using(HttpClient client = new HttpClient()){for (int i = 0; i < n; i++){string html = await new HttpClient().GetStringAsync(url);Console.WriteLine($"{DateTime.Now}:{html}");if (token.IsCancellationRequested){Console.WriteLine("超时任务取消");break;}}}}
}
当我们打印数据的时候,请求超过5秒还没有结束的话我们就手动取消异步操作:
Task类方法:在Task类中有许多方法可以使用,以下是其常用的方法讲解:
1)Task.WhenAny():任何一个Task完成,Task就完成
2)Task.WhenAll():所有Task完成Task才完成,用于等待多个任务执行结束不在乎顺序
3)Task.FromResult():创建普通数值的Task对象
如下我们可同WhenAll拿到所有文件的数据:
class Program
{static async Task Main(string[] args){Task<string> t1 = File.ReadAllTextAsync(@"d:\test\1.txt");Task<string> t2 = File.ReadAllTextAsync(@"d:\test\2.txt");Task<string> t3 = File.ReadAllTextAsync(@"d:\test\3.txt");string[] result = await Task.WhenAll(t1, t2, t3);}
}
相关文章:
如何在 .NET Core 中轻松实现异步编程并提升性能
目录 初识异步编程 与多线程关系 异步编程操作 初识异步编程 异步编程:是指在执行某些任务时程序可以在等待某个操作完成的过程中继续执行其他任务,而不是阻塞当前线程,这在处理I/O密集型操作(如文件读取、数据库查询、网络请求等)时尤为重…...
makefile文件
简介: 自动化编译:只需要一个make命令,整个工程自动编译 提高编译效率:再次编译时,只编译修改的文件(查看时间戳,根据修改文件的时间判断文件是否被修改) 基本语法: …...
MybatisPlus使用LambdaQueryWrapper更新时 int默认值问题
问题: User user new User();user.setBalance(1000);QueryWrapper<User> queryWrapper new QueryWrapper<>();queryWrapper.eq("username","Jack");userMapper.update(user, queryWrapper);通过用户名,更新金额&…...
泷羽sec学习打卡-brupsuite7搭建IP炮台
声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-IP炮台搭建 搭建炮台服务端安装zmap1、更新系统和安装基础依赖ÿ…...
WPF系列一:窗口设置无边框
WindowStyle 设置:WindowStyle"None",窗口无法拖拽,但可纵向和横向拉伸 <Window x:Class"WPFDemo.MainWindow.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x&quo…...
《C++与 Armadillo:线性代数助力人工智能算法简化之路》
在人工智能领域,线性代数运算可谓是构建各类模型与算法的基石。从神经网络中的矩阵乘法、向量运算,到数据处理中的特征分解、奇异值分解等,无一不依赖高效且精准的线性代数计算。而 C作为一种强大且高效的编程语言,在人工智能开发…...
【新界面】基于卷积神经网络的垃圾分类(Matlab)
基于CNN的垃圾识别与分类GUI【新界面】 有需要可直接联系我,基本都在在线,能秒回!可加我看演示视频,不懂可以远程教学 1.此项目设计包括两份完整的源代码,有GUI界面的代码和无GUI界面系统的代码。 (以下部…...
阿尔茨海默症数据集,使用yolo,voc,coco格式对2013张原始图片进行标注,可识别轻微,中等和正常的症状
阿尔茨海默症数据集,使用yolo,voc,coco格式对2013张原始图片进行标注,可识别轻微,中等,严重和正常的症状 数据集分割 训练组100% 2013图片 有效集% 0图片 测试集…...
评估二分类模型性能之AUC-ROC 曲线
AUC-ROC 曲线 是评估二分类模型性能的重要工具。它结合了 受试者工作特性曲线 (Receiver Operating Characteristic, ROC) 和 曲线下面积 (Area Under the Curve, AUC),全面衡量分类器在不同阈值下的表现。 概念解释 1. ROC 曲线 ROC 曲线展示了分类器在不同阈值下…...
睡岗和玩手机数据集,4653张原始图,支持YOLO,VOC XML,COCO JSON格式的标注
睡岗和玩手机数据集,4653张原始图,支持YOLO,VOC XML,COCO JSON格式的标注 数据集分割 训练组70% 3257图片 有效集20% 931图片 测试集10% 465图片 预处理 没有采用任何预处…...
景联文科技:精准语音标注,驱动语音技术新发展
在人工智能迅速发展的今天,语音技术的应用已经渗透到我们生活的方方面面。从智能音箱、语音助手到自动语音识别系统,高质量的语音数据是这些应用成功的关键。景联文科技作为领先的AI数据服务提供商,专注于为客户提供高精度、高效的语音标注服…...
Linux 查看目录命令 ls 详细介绍
Linux 和 Unix 系统中 ls 命令是用于列出目录内容。用户可以查看指定目录下的文件和子目录,还可以获取有关这些文件和子目录的详细信息。 基本语法: ls [选项] [目录]如果不指定目录,ls 将列出当前工作目录下的内容。 01、-a 或 --all ls…...
Flux Tools 结构简析
Flux Tools 结构简析 BFL 这次一共发布了 Canny、Depth、Redux、Fill 四个 Tools 模型系列,分别对应我们熟悉的 ControlNets、Image Variation(IP Adapter)和 Inpainting 三种图片条件控制方法。虽然实现功能是相同的,但是其具体…...
从零开始:PHP基础教程系列-第13篇:构建简单的Web应用
从零开始:PHP基础教程系列 第13篇:构建简单的Web应用 在本篇文章中,我们将学习如何使用PHP构建一个简单的Web应用。这个应用将实现用户注册和登录功能,并使用PDO与MySQL数据库进行交互。我们将逐步实现这个应用的基本功能。 一…...
文件夹属性变0字节:全面解析与恢复指南
一、文件夹属性变0字节现象概述 在日常使用电脑的过程中,我们可能会遇到文件夹属性突然变为0字节的情况。这意味着文件夹中的文件列表或元数据被某种方式清空或损坏,导致系统无法正确读取文件夹的内容。当您尝试打开此类文件夹时,通常会收到…...
PDFMathTranslate 一个基于AI优秀的PDF论文翻译工具
PDFMathTranslate 是一个设想中的工具,旨在翻译PDF文档中的数学内容。以下是这个工具的主要特点和使用方法: 功能特点 数学公式识别:利用先进的OCR(光学字符识别)技术,精准识别PDF文档中的数学公式和文本…...
35. Three.js案例-创建带阴影的球体与平面
35. Three.js案例-创建带阴影的球体与平面 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中用于渲染场景的主要类之一,它负责将场景中的对象渲染到画布上。 构造器 new THREE.WebGLRenderer(parameters : Object) 参数类型描述parametersObject可选…...
【Linux】深入理解进程信号机制:信号的产生、捕获与阻塞
🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 时间不语,却回答了所有问题 目录 📚前言 📚一、信号的本质 📖1.异步通信 📖2.信…...
Vue3.0使用JavaScript脚本实现Vue Router路由:页面跳转、获取URL参数
Vue 使用 Vue Router 路由系列文章: 《Vue使用Vue Router路由:开发单页应用》 《Vue使用Vue Router路由:通过URL传递与获取参数》 《Vue3.0使用JavaScript脚本实现Vue Router路由:页面跳转、获取URL参数》 1、路由基础 在单页 Web 应用中,整个项目只有一个 HTML 文件,不…...
2025山东科技大学考研专业课复习资料一览
[冲刺]2025年山东科技大学020200应用经济学《814经济学之西方经济学[宏观部分]》考研学霸狂刷870题[简答论述计算题]1小时前[强化]2025年山东科技大学085600材料与化工《817物理化学》考研强化检测5套卷22小时前[冲刺]2025年山东科技大学030100法学《704综合一[法理学、国际法学…...
lambda 表达式 闭包写法
lambda 表达式 1.用于 匿名委托函数表达 2.用于linq 查询表达 匿名方法表达 (参数)》{ 逻辑} 比如 (x,y)>{return xy;} 如果一个参数可不带(),如果逻辑简单可以不{} 比如 x>x 如果没有参…...
什么是正则化?Regularization: The Stabilizer of Machine Learning Models(中英双语)
正则化:机器学习模型的稳定器 1. 什么是正则化? 正则化(Regularization)是一种在机器学习模型训练中,通过约束模型复杂性以防止过拟合的技术。 它的核心目标是让模型不仅在训练集上表现良好,还能在测试集上…...
【西门子PLC.博途】——面向对象编程及输入输出映射FC块
当我们做面向对象编程的时候,需要用到输入输出的映射。这样建立的变量就能够被复用,从而最大化利用了我们建立的udt对象。 下面就来讲讲映射是什么。 从本质上来说,映射就是拿实际物理对象对应程序虚拟对象,假设程序对象是I0.0&…...
CS61a.1 textbook1.2 编程要素
1.structure and interpretation of computer programs Python 内置了对各种常见编程活动的支持, 例如,操作文本、显示图形以及通过 互联网。Python 代码行 >>> from urllib.request import urlopen是一个 import 语句,用于加载用…...
计算机毕业设计Django+Tensorflow音乐推荐系统 音乐可视化 卷积神经网络CNN LSTM音乐情感分析 机器学习 深度学习 Flask
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
使用国内镜像网站在线下载安装Qt(解决官网慢的问题)——Qt
国内镜像网站 中国科学技术大学:http://mirrors.ustc.edu.cn/qtproject/清华大学:https://mirrors.tuna.tsinghua.edu.cn/qt/北京理工大学:http://mirror.bit.edu.cn/qtproject/ 南京大学:https://mirror.nju.edu.cn/qt腾讯镜像&…...
乳腺癌多模态诊断解释框架:CNN + 可解释 AI 可视化
乳腺癌多模态诊断解释框架:CNN 可解释 AI 可视化 论文大纲理解1. 确认目标2. 分析过程(目标-手段分析)3. 实现步骤4. 效果展示 结构分析1. 层级结构分析叠加形态(从基础到高级)构成形态(部分到整体&#x…...
MySQL篇之对MySQL进行参数优化,提高MySQL性能
1. MySQL参数优化说明 MySQL 参数调优是提高数据库性能的重要手段之一。通过调整 MySQL 的配置参数,可以优化查询速度、提升并发处理能力、减少资源消耗等。 MySQL 的性能优化涉及到多个方面,包括内存管理、磁盘 I/O、查询优化、连接管理、复制配置等。…...
Scratch节日 | 快乐圣诞节——用编程传递节日祝福! ✨
今天为大家推荐一款充满节日气氛的Scratch项目——《快乐圣诞节》!这款圣诞主题动画贺卡项目不仅让小朋友们学习编程知识,还提供了一种用创意传递祝福的方式。通过编程打造星星闪烁的圣诞树,播放经典圣诞音乐,制作一张属于自己的节…...
android studio更改应用图片,和应用名字。
更改应用图标,和名字 先打开AndroidManifest.xml文件。 更改图片文件名字( 右键-->构建-->重命名(R))...
PHP8.4下webman直接使用topthink/think-orm
环境信息 操作系统win11php 8.4.1webman-framework ^1.6.8MySQL 8.4.3topthink/think-orm ^3.0 说明 PHP8.3以下版本 直接使用webman提供的webman/think-orm更方便。 PHP 环境换为 8.4 使用webman/think-orm 报了个错;所以换topthink/think-orm,根据文…...
uniapp 微信小程序 功能入口
单行单独展示 效果图 html <view class"shopchoose flex jsb ac" click"routerTo(要跳转的页面)"><view class"flex ac"><image src"/static/dyd.png" mode"aspectFit" class"shopchooseimg"&g…...
Halcon 机器视觉案例 之 连接件测量
第一篇 机器视觉案例 之 连接件测量 文章目录 第一篇 机器视觉案例 之 连接件测量1.案例要求2.实现思路2.1 读取单张图片并创建图像模板2.2 画出圆和直线2.3 创建测量模型2.4 循环读取多张图片并查找图像中连接件位置2.5 根据偏移量补偿使得测量模型移动至指定位置 3.实现效果4…...
druid与pgsql结合踩坑记
最近项目里面突然出现一个怪问题,数据库是pgsql,jdbc连接池是alibaba开源的druid,idea里面直接启动没问题,打完包放在centos上和windows上cmd窗口都能直接用java -jar命令启动,但是放到国产信创系统上就是报错…...
Windows环境 (Ubuntu 24.04.1 LTS ) 国内镜像,用apt-get命令安装RabbitMQ,java代码样例
一、环境 Windows11 WSL(Ubuntu 24.04.1) 二、思路 1 用Windows中的Ubuntu安装RabbitMQ,贴近Linux的线上环境; 2 RabbitMQ用erlang语言编写的,先安装erlang的运行环境; 2 用Linux的apt-get命令安装,解决软件依赖…...
RabbitMQ的核心组件有哪些?
大家好,我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些?】面试题。希望对大家有帮助; RabbitMQ的核心组件有哪些? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理(Messag…...
mysql免安装版配置教程
一、将压缩包解压至你想要放置的文件夹中,注意:绝对路径中要避免出现中文 二、在解压目录下新建my.ini文件,已经有的就直接覆盖 my.ini文件内容 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirD:\\tools\\mysql-8.1.0-win…...
ubuntu+ros新手笔记(三):21讲没讲到的MoveIt2
1 安装MoveIt2 安装参照在ROS2中,通过MoveIt2控制Gazebo中的自定义机械手 安装 MoveIt2可以选择自己编译源码安装,或者直接从二进制安装。 个人建议直接二进制安装,可以省很多事。 sudo apt install ros-humble-moveitmoveit-setup-assistan…...
Charles简单压力测试
01、接口请求次数,并发量,请求延迟时间均可配置 选中需要进行测试的接口,鼠标右键选中【repeat advance】 02、设置并发参数 下面的图中,选择了1个接口,每次迭代中1个接口同时请求,迭代1000次(…...
决策树的生成与剪枝
决策树的生成与剪枝 决策树的生成生成决策树的过程决策树的生成算法 决策树的剪枝决策树的损失函数决策树的剪枝算法 代码 决策树的生成 生成决策树的过程 为了方便分析描述,我们对上节课中的训练样本进行编号,每个样本加一个ID值,如图所示…...
对象克隆与单例模式的实现
一、引言 在 C 编程中,对象克隆和单例模式是两个非常重要的概念。对象克隆可以帮助我们快速创建具有相同状态的对象副本,而单例模式则可以确保一个类只有一个实例,并提供全局访问点。本文将详细介绍 C 中如何实现对象的克隆以及单例模式。 …...
在 Linux 系统中,让 apt 使用 HTTP 代理
在 Linux 系统中,要让 apt 使用 HTTP 代理,有几种方法可以实现: ### 1. 临时设置代理 你可以通过设置环境变量来临时为 apt 命令设置代理。这种方法不需要修改任何配置文件,只需在命令行中设置环境变量即可。例如: …...
中国气象局:2024年第二批“气象数据要素×”典型案例(附下载)
11月25日,中国气象局通报2024年第二批“气象数据要素”典型案例。此次遴选充分结合首届“数据要素”大赛获奖案例,旨在进一步号召各级气象部门充分学习借鉴先进经验和做法,持续推动高价值气象数据产品开发利用,挖掘气象数据要素应…...
Android绘图Path基于LinearGradient线性渐变,Kotlin(1)
Android绘图Path基于LinearGradient线性渐变,Kotlin(1) import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.LinearGradient import android.graphics.Paint import and…...
基础入门-APP应用微信小程序原生态开发H5+Vue技术WEB封装打包反编译抓包点
知识点: 1、基础入门-APP应用-开发架构安全问题 2、基础入门-小程序应用-开发架构安全问题 通用: 1、反编译-得到源码-源码提取资产(泄漏的配置信息)-安全测试 2、抓包-资产-安全测试 一、演示案例-移动App-开发架构-原生&H…...
vue+ts提交数据时不提交(剔除)某项数据
关键代码 // 假设这是原始要提交的数据数组 const dataArray [{areaConfId: ,areaName: ,cityInfo: [],provinceList: [],cityList: []} ];// 使用map方法遍历数组中的每个对象,通过解构赋值和对象展开运算符去除cityInfo字段 const newDataArray dataArray.map…...
乐凡信息智能安全管控方案:助力油气田行业安全管控多方位升级
我国油田地域广阔,分布着大量各种油井,油井开采设备的连续稳定运行是保证石油开采的首要条件。然而,由于油田多位于特殊地理环境中,因而实现油井之间的通信首要问题就是要克服地理环境所带来的限制,传统通信系统的建设…...
Jenkins搭建并与Harbor集成上传镜像
Jenkins介绍 Jenkins 是一个开源的自动化服务器,广泛用于持续集成(CI)和持续交付(CD)的实践中。它帮助开发人员自动化构建、测试和部署过程,从而提高开发效率、代码质量和项目交付速度。通过丰富的插件支持…...
FutureCompletableFuture实战
1. Callable&Future&FutureTask介绍 直接继承Thread或者实现Runnable接口都可以创建线程,但是这两种方法都有一个问题就是:没有返回值,也就是不能获取执行完的结果。因此java1.5就提供了Callable接口来实现这一场景,而Fu…...
Amazon与Shopee平台对比:跨境卖家如何选对平台打开市场?
在跨境电商领域,选择合适的平台对卖家能否成功打开市场至关重要。如今,Amazon和Shopee成为了众多卖家的热门选择。一个以全球化布局和高端市场著称,一个则专注东南亚新兴市场的潜力。两者各有优势,但也需要根据卖家的业务模式、目…...