Task 异步小技巧
原文地址:Task 异步小技巧 - 一事冇诚 - 博客园 (cnblogs.com)
async Task 语法糖出来后,异步编程变得非常简单,适合需要耗费较长时间的任务。
有些小伙伴使用后可能会非常疑惑,使用异步和同步,在耗时上几乎没有差别。
下面我们看一个例子,场景是需要调用多个第三方的WebApi,分别是获取名称、年龄、性别,由于网络环境等原因,api响应时间可能会接近1秒
1 public async Task Test()
2 {
3 var sw = new Stopwatch();
4 sw.Start();
5
6 var userName = await GetUserNameAsync();
7 var userAge = await GetUserAgeAsync();
8 var userSex = await GetUserSexAsync();
9
10 sw.Stop();
11 var ts = sw.Elapsed;
12 Console.WriteLine($"总共耗时:{ts.TotalMilliseconds}ms");
13 }
14
15 private async Task<string> GetUserNameAsync()
16 {
17 await Task.Delay(500);
18 return "小明";
19 }
20
21 private async Task<string> GetUserAgeAsync()
22 {
23 await Task.Delay(800);
24 return "11";
25 }
26
27 private async Task<string> GetUserSexAsync()
28 {
29 await Task.Delay(900);
30 return "11";
31 }
运行后发现,这个时间2秒多,这用户体验肯定是无法忍受的

导致这样结果的原因是每次进行异步调用的时候,都在异步函数前加上了 await ,这会导致该线程阻塞,等待直到结果返回,每个异步函数都await,时间自然就叠加了,为了解决这个问题,使用一个小技巧,可以将代码改成下面这样
1 public async Task Test()
2 {
3 var sw = new Stopwatch();
4 sw.Start();
5
6 var userNameTask = GetUserNameAsync();
7 var userAgeTask = GetUserAgeAsync();
8 var userSexTask = GetUserSexAsync();
9
10 var userName = await userNameTask;
11 var userAge = await userAgeTask;
12 var userSex = await userSexTask;
13
14 sw.Stop();
15 var ts = sw.Elapsed;
16 Console.WriteLine($"总共耗时:{ts.TotalMilliseconds}ms");
17 }
18
19 private async Task<string> GetUserNameAsync()
20 {
21 await Task.Delay(500);
22 return "小明";
23 }
24
25 private async Task<string> GetUserAgeAsync()
26 {
27 await Task.Delay(800);
28 return "11";
29 }
30
31 private async Task<string> GetUserSexAsync()
32 {
33 await Task.Delay(900);
34 return "11";
35 }
这次运行的总耗时,就是3个异步中,耗时最长那个 GetUserSexAsync

为什么会这样呢,这个小技巧的关键是这里,当执行到异步函数的时候,不加 await,不进行等待,这样就不会造成阻塞,让这些任务乖乖在别的线程的执行,当需要用到他们的时候,再去等待返回值,所以时间上不会进行叠加,哪个最长,总耗时就是哪个
1 var userNameTask = GetUserNameAsync();
2 var userAgeTask = GetUserAgeAsync();
3 var userSexTask = GetUserSexAsync();
4
5 var userName = await userNameTask;
6 var userAge = await userAgeTask;
7 var userSex = await userSexTask;
Task 异步小技巧的更多相关文章
- 异步处理的框架Sanic的使用方法和小技巧
		
Sanic是异步处理的框架,运用Sanic可以开发快速异步响应的web程序.想必大家看到这个都会比较期待和兴奋. 那么如何使用Sanic来实现快速响应呢?我们先来看一看Sanic的基本介绍. Sani ...
 - Windows Azure一些小技巧集合
		
我最近做了一个Windows Azure上面的项目,自己在做的过程中遇到了很多问题.有的是我自己摸索解决,有的是到网上寻找零碎的信息结合起来解决的.我感觉应当把某些解决方法集中一下,方便我以后查阅,也 ...
 - 10个小技巧助您写出高性能的ASP.NET Core代码
		
今天这篇文章我们来聊一聊如何提升并优化ASP.NET Core应用程序的性能,本文的大部分内容来自翻译,当然中间穿插着自己的理解,希望对大家有所帮助!话不多说开始今天的主题吧! 我们都知道性能是公共网 ...
 - 前端网络、JavaScript优化以及开发小技巧
		
一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...
 - iOS:小技巧(不断更新)
		
记录下一些不常用技巧,以防忘记,复制用. 1.获取当前的View在Window的frame: UIWindow * window=[[[UIApplication sharedApplication] ...
 - Java在处理大数据的时候一些小技巧
		
Java在处理大数据的时候一些小技巧 发布时间:2013-05-09 00:00:00 来源:中国IT实验室 作者:佚名 关键字:Java 众所周知,java在处理数据量比较大的时候,加载到内存必 ...
 - ( 译、持续更新 ) JavaScript 上分小技巧(四)
		
后续如有内容,本篇将会照常更新并排满15个知识点,以下是其他几篇译文的地址: 第一篇地址:( 译.持续更新 ) JavaScript 上分小技巧(一) 第二篇地址:( 译.持续更新 ) JavaScr ...
 - ( 译、持续更新 ) JavaScript 上分小技巧(三)
		
最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...
 - 文件上传小技巧/原生态【html篇】
		
引语:大家都知道,html中上传文件就一个input,type=file就搞定了.但是,这个标签的样式,实在不值得提点什么,要改动他的样式,恐怕也是较难的.但是其实挺简单,今天就来说说上传文件小技巧吧 ...
 
随机推荐
- linux使用xampp安装MediaWiki环境
			
1.下载并安装xampp 下载xampp 在下载页面下载. 放置到相应目录 将xampp-linux-x64-5.6.3-0-installer.run文件复制到部署机器的/root目录下 安装 [r ...
 - 【C语言】第2章 算法 — 程序的灵魂
			
第2章 算法 - 程序的灵魂 一个程序主要包括以下两方面的信息: 对数据的描述.在程序中要指定用到哪些数据以及这些数据的类型和数据的组织形式 也就是数据结构(data structure) 对操作的描 ...
 - JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )
			
题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...
 - SpringBoot2.x+mybatis plus3.x集成Activit7版本
			
最近在写一个开源项目ruoyi-vue-pro,暂时负责Activiti7工作流的搭建,接这个任务一个原因,是比较好奇Activiti7版本与先前的5.6版本究竟有什么区别,因为先前在工作当中,最开始 ...
 - k8s 存活探针,滚动更新
			
文章原文 存活探针 Kubelet使用liveness probe(存活探针)来确定何时重启容器.例如,当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于 ...
 - DorisDB升级为StarRocks,全面开源!
			
今天被朋友圈刷屏了,StarRocks开源--携手未来,星辰大海! 原文链接:StarRocks开源--携手未来,星辰大海! 可能大家对StarRocks不太熟悉,但是DorisDB想必都是听说过的. ...
 - IPv4掩码与掩码位数的转换
			
1. 根据掩码获取掩码的位数 int mask2len(unsigned int mask) { /*eg: 255.255.255.0 255.0.255.255.0*/ int bit=0,len ...
 - Typeora 图床设置
			
Typeora 文章中的图片 使用 Github 作为图床. 使用 PicGo 上传图片到 Github 并获取图片链接. 设置 Typeora 的上传服务. 一.Github 作为图床 创建 Rep ...
 - UI自动化测试:App的Webview页面元素左滑
			
一.前言 在做App自动化测试时,我们会遇到如上图所示的列表数据页面左滑删除场景,一般可以通过location.rect方法获取对应列表的元素坐标,然后使用TouchAction或者swipe滑动 ...
 - PHP匿名类的用法
			
在PHP7之后,PHP中加入了匿名类的特性.匿名类和匿名方法让PHP成为了更现代化的语言,也让我们的代码开发工作越来越方便.我们先来看看匿名类的简单使用. // 直接定义 $objA = new cl ...