同步方法 调用异步防范_.NET Web应用中为什么要使用async/await异步编程?

792370b9ebe3e29e66ae634b994e7f0e.png
布莱恩特:.NET Core开发精选文章目录,持续更新,欢迎投稿!​zhuanlan.zhihu.com
c4673ada4c68ff596adb5b29ed289c5b.png

154271e9ec8bd630c2a42cae5b00bc93.png

前言

1.什么是async/await?

await和async是.NET Framework4.5框架、C#5.0语法里面出现的技术,目的是用于简化异步编程模型。

2.async和await的关系?

async和await是成对出现的。async出现在方法的声明里,用于批注一个异步方法。光有async是没有意义的。await出现在方法内部,Task前面。只能在使用async关键字批注的方法中使用await关键字。

private async Task DoSomething()
{await Task.Delay(TimeSpan.FromSeconds(10));
}

3.async/await会创建新的线程吗?

不会。async/await关键字本身是不会创建新的线程的,但是被await的方法内部一般会创建新的线程。

http://4.asp.net mvc/webapi action中使用async/await会提高请求的响应速度吗?

不会。

正题

我们都知道web应用不同于winform、wpf等客户端应用,客户端应用为了保证UI渲染的一致性往往都是采用单线程模式,这个UI线程称为主线程,如果在主线程做耗时操作就会导致程序界面假死,所以客户端开发中使用多线程异步编程非常必要。

可web应用本身就是多线程模式,服务器会为每个请求分配工作线程。

既然async/await不能创建新线程,又不能使提高请求的响应速度,那.NET Web应用中为什么要使用async/await异步编程呢?

在 web 服务器上,.NET Framework 维护用于处理 http://ASP.NET请求的线程池。当请求到达时,将调度池中的线程以处理该请求。如果以同步方式处理请求,则处理请求的线程将在处理请求时处于繁忙状态,并且该线程无法处理其他请求。
在启动时看到大量并发请求的 web 应用中,或具有突发负载(其中并发增长突然增加)时,使 web 服务调用异步会提高应用程序的响应能力。异步请求与同步请求所需的处理时间相同。 如果请求发出需要两秒钟时间才能完成的 web 服务调用,则该请求将需要两秒钟,无论是同步执行还是异步执行。但是,在异步调用期间,线程在等待第一个请求完成时不会被阻止响应其他请求。因此,当有多个并发请求调用长时间运行的操作时,异步请求会阻止请求队列和线程池的增长。

下面用代码来实际测试一下: 先是同步的方式,代码很简单,就是输出一下请求开始和结束的时间和线程ID:

public ActionResult Index()
{DateTime startTime = DateTime.Now;//进入DoSomething方法前的时间var startThreadId = Thread.CurrentThread.ManagedThreadId;//进入DoSomething方法前的线程IDDoSomething();//耗时操作DateTime endTime = DateTime.Now;//完成DoSomething方法的时间var endThreadId = Thread.CurrentThread.ManagedThreadId;//完成DoSomething方法后的线程IDreturn Content($"startTime:{ startTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } startThreadId:{ startThreadId }<br/>endTime:{ endTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } endThreadId:{ endThreadId }<br/><br/>");
}/// <summary>
/// 耗时操作
/// </summary>
/// <returns></returns>private void DoSomething(){Thread.Sleep(10000);}

使用浏览器开3个标签页进行测试(因为浏览器对同一域名下的连接数有限制,一般是6个左右,所以就弄3个吧):

98f9518e42273a1182bfaa99dcbd9538.png

07bdb5fcc418342a5eea915ca07b48a2.png

4203d12c2ff6e98ca5a4d808ff2a8b3a.png

可以看到耗时都是10秒,开始和结束的线程ID一致。下面改造成异步的:

        public async Task<ActionResult> Index(){DateTime startTime = DateTime.Now;//进入DoSomething方法前的时间var startThreadId = Thread.CurrentThread.ManagedThreadId;//进入DoSomething方法前的线程IDawait DoSomething();//耗时操作DateTime endTime = DateTime.Now;//完成DoSomething方法的时间var endThreadId = Thread.CurrentThread.ManagedThreadId;//完成DoSomething方法后的线程IDreturn Content($"startTime:{ startTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } startThreadId:{ startThreadId }<br/>endTime:{ endTime.ToString("yyyy-MM-dd HH:mm:ss:fff") } endThreadId:{ endThreadId }<br/><br/>");}/// <summary>/// 耗时操作/// </summary>/// <returns></returns>private async Task DoSomething(){await Task.Run(() => Thread.Sleep(10000));}

结果:

21b46fe956e648646ce20a5a64af96c6.png

e0899fbcaa83b52961aeacb379ea7f0f.png

c7ef8f1b49b9330f152a69451dc1191d.png

可以看到3次请求中,虽然耗时都是10秒,但是出现了开始和结束的线程ID不一致的情况,ID为22的这个线程工作了多次,这意味着使用异步方式在同一时间可以处理更多的请求!

IIS默认队列长度:

e31792da984274d7c12b1f6c323c996d.png
await关键字不会阻塞线程直到任务完成。它将方法的其余部分注册为任务的回调,并立即返回。当await的任务最终完成时,它将调用该回调,并因此在其中断时继续执行方法。

简单来说:就是使用同步方法时,线程会被耗时操作一直占有,直到耗时操作完成。而使用异步方法,程序走到await关键字时会立即return,释放线程,余下的代码会放进一个回调中(Task.GetAwaiter()的UnsafeOnCompleted(Action)回调),耗时操作完成时才会回调执行,所以async/await是语法糖,其本质是一个状态机。

那是不是所有的action都要用async/await呢?

不是。

一般的磁盘IO或者网络请求等耗时操作才考虑使用异步,不要为了异步而异步,异步也是需要消耗性能的,使用不合理会适得其反。

结论

async/await异步编程不能提升响应速度,但是可以提升响应能力(吞吐量)。异步和同步各有优劣,要合理选择,不要为了异步而异步。

来源:https://www.cnblogs.com/xhznl/p/13064731.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[bzoj2875][Noi2012]随机数生成器

来自FallDream的博客&#xff0c;未经允许&#xff0c;请勿转载&#xff0c;谢谢。 栋栋最近迷上了随机算法&#xff0c;而随机数是生成随机算法的基础。栋栋准备使用线性同余法&#xff08;Linear Congruential Method&#xff09;来生成一个随机数列&#xff0c;这种方法需要…

戴尔电脑开机黑屏怎么办_笔记本电脑开机黑屏怎么办

笔记本电脑开机黑屏是什么原因,电脑黑屏问题如何修复解决众所周知笔记本电脑的散热性能不是特别好&#xff0c;长时间使用笔记本电脑就可能会出现笔记本发烫的状况&#xff0c;严重的有可能造成笔记本电脑出现问题。人们在使用笔记本电脑时可能会出现电脑开机黑屏等情况&#x…

ftp服务器上传文件提示451,解决IIS7之FTP部分文件上传451错误

单位的需要搭建一个FTP&#xff0c;于是就直接使用服务器上的IIS添加了FTP组件&#xff0c;大家都知道IIS组件中的ftp服务器功能比较简单&#xff0c;但是设置起来不太个性化&#xff01;配置好以后&#xff0c;添加一个组的用户具有上传及读取权限&#xff0c;使用Flashfxp软件…

存根类 测试代码 java_嘲弄和存根–了解Mockito的测试双打

存根类 测试代码 java介绍 我遇到的一件事是使用模拟框架的团队假设他们在模拟。 他们并不知道Mocks只是Gerard Meszaros在xunitpatterns.com上分类的“测试双打”之一。 重要的是要认识到每种类型的双重测试在测试中扮演着不同的角色。 用与学习不同模式或重构相同的方式&a…

只会python怎么挣钱_业余学python有用吗

Python的火热我就不细说了&#xff0c;大家都是编程老司机&#xff0c;对最前沿最火热的编程语言肯定比我还了解。前几天&#xff0c;我看了一篇“如何用Python制造一个抖音小姐姐发掘器&#xff1f;”&#xff0c;阅读量竟然比头条上的还多了一倍。可见Python的火热&#xff0…

python3打包exe运行没反应_python selenium运行,打包exe常见问题解决方法

selenium是一款优秀的自动化测试工具&#xff0c;支持的语言也非常广泛&#xff0c;其中以python语言最为高效简洁&#xff0c;本文以Python3.5.2为例。首先需要安装selenium插件&#xff0c;命令行下pip install selenium 或如果安装的有Python2.x版本的需用pip3 install sele…

ansible copy file

ansible xxxip -m copy -a src/localdir/file dest/sss/xxx/basic_search/bin/转载于:https://www.cnblogs.com/lavin/p/6740312.html

ajax和for循环谁难,关于“for”循环中jquery $ .ajax的问题

我相信有一些事情正在发生。首先&#xff0c;$ temp_id变量被提升到函数的顶部&#xff0c;所以它相当于这样做&#xff1a;$.ajax({……success:function(){var $temp_id;for (var i 0; i < $children.length; i) {$temp_id $children.eq(i).attr("id");其次&a…

物联网项目:将Arduino连接到Ubidots和Android –第1部分

这个物联网项目探索了物联网的一个重要方面&#xff1a;如何使用以太网屏蔽将Arduino连接到物联网云平台 。 这方面很重要&#xff0c;因为可以将数据存储在云中然后进行分析。 一旦数据&#xff08;如传感器值&#xff09;存储在云中&#xff0c;便可以使用智能手机访问数据并…

iphone黑屏转圈_iphone XR被曝新BUG,众多用户中招,无规律黑屏假死

进入今年一月份以来&#xff0c;苹果放宽了对iphone的定价&#xff0c;所以各大电商都对多款iphone XR进行了上千元的降价。这也让iphone XR瞬间取代了华为MATE 20 PRO成为新的“真香机”。而随着iphone XR的用户越来越多&#xff0c;这款手机也再次爆出新的BUG。根据网友的反馈…

怎么邀请人加入组队_糖豆人:终极淘汰赛怎么玩?玩法技巧介绍

这几天玩糖豆人&#xff1a;终极淘汰赛的玩家都在问&#xff0c;这个游戏模式怎么玩&#xff0c;糖豆人终极淘汰赛是一款60人同台竞争的卡通吃鸡游戏。想要获胜还是有一定难度的&#xff0c;战神游戏加速器为大家带来这款游戏的基础操作和具体玩法&#xff0c;超低延迟极速体验…

2017年4月21号课堂笔记

2017年4月21号 星期五 空气质量&#xff1a;良 内容&#xff1a;XML&#xff0c;Dom4j解析XML文件&#xff0c;单例 一、XML 老师代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?><!-- XML的注释xml是什么&#xff1f; 可扩展的标记语言…

服务器物理内存总是九十几,服务器物理内存使用率90以上

服务器物理内存使用率90以上 内容精选换一换开启弹性云服务器的虚拟内存后&#xff0c;会导致硬盘I/O性能下降&#xff0c;因此&#xff0c;平台提供的Windows弹性云服务器默认未配置虚拟内存。如果弹性云服务器内存不足&#xff0c;建议通过“变更规格”操作来扩大内存。如果业…

比较二进制_浮点数比较的精度问题

引言 先举个例子&#xff1a;#include <stdio.h>int main() {float a 0.1;float b 0.2;float c a b;if(c 0.3){printf("c 0.3n");}else{printf("0.1 0.2 ! 0.3n");}return 0; }如果变量a,b换0.75&#xff0c;0.5可以看出运行出c 1.25,说明浮…

open表和closed表_excel工作表合并,多文件数据一键合成

工作中 遇到十几个甚至几十个单独工作excel文件要合并成一个怎么办&#xff0c;难道还按照老办法复制工作表?几个还好说&#xff0c;遇到十几个几十个文件&#xff0c;手速不够快的宝宝心里苦。那么&#xff0c;有没有什么日常偷懒神技&#xff0c;一键合成多个excel文件&…

濡沫江湖一直显示获取服务器地址,濡沫江湖采集点坐标大全

濡沫江湖每个地图都有采集点&#xff0c;那么濡沫江湖采集点具体坐标是多少&#xff1f;下面9k9k小编就为大家整理带来濡沫江湖采集点坐标大全&#xff1a;小渔村(35,4)采集铜矿石、碎铁块小渔村(38&#xff0c;16)采集药草、杂草小渔村(14,35)采集亚麻、杂草小渔村(13,12)采集…

jsf集成spring_Spring和JSF集成:转换器

jsf集成spring使用任何Web框架时&#xff0c;都不可避免地需要将用户输入的数据从String为其他类型。 尽管Spring和JSF在设计和功能上确实有很大的不同&#xff0c;但它们都具有转换器策略来处理此问题。 让我们从春天开始。 Spring 3引入了一个全新的转换框架&#xff0c;该框…

在python中、实例变量在类的内部通过_[宜配屋]听图阁

1、类变量、实例变量概念类变量&#xff1a;类变量就是定义在类中&#xff0c;但是在函数体之外的变量。通常不使用self.变量名赋值的变量。类变量通常不作为类的实例变量的&#xff0c;类变量对于所有实例化的对象中是公用的。实例变量&#xff1a;实例变量是定义在方法中的变…

java第五次作业

《Java技术》第五次作业 &#xff08;一&#xff09;学习总结 1.在上周完成的思维导图基础上&#xff0c;补充本周的学习内容&#xff0c;对Java面向对象编程的知识点做一个全面的总结。 2.汽车租赁公司&#xff0c;出租汽车种类有客车、货车和皮卡三种&#xff0c;每辆汽车除了…

mysqld已删除但仍占用空间的_Windows 10删除备份文件方法

Windows具有许多内置备份功能&#xff0c;包括卷影副本&#xff0c;系统还原点和整个系统备份。尽管它们既不是最可靠也不是功能最丰富的备份解决方案&#xff0c;但它们确实提供了一种备份系统和个人数据的不错的方式。Windows内置备份工具的问题之一是它们几乎过于安静和方便…