async/await的一些用法
普通函数
string Func()
{
string x = X();
string y = Y();
string z = Z(); return x + y + z;
}
X(), Y(), Z()内部都Sleep 10s, 则Func()耗时30s
异步函数
async string FuncAsync()
{
string x = await XAsync();
string y = await YAsync();
string z = await ZAsync(); return x + y + z;
}
假设 XAsync(), YAsync(), YAsync()内部都Sleep10s, 则FuncAync()还是耗时多少呢?
整个FuncAsync会被拆成如下部分:
- FuncAsync-开始部分();
- XAsync();
- FuncAsync-中间部分1();
- YAsync();
- FuncAsync-中间部分2();
- ZAsync();
- FuncAsync-结束部分();
这些部分会被.NET同步上下文SynchronizationContext在同一个线程依次执行,如下:
- 同步上下文执行 FuncAsync-开始部分();
- 同步上下文执行 XAsync(); //内部调用了Sleep10s, 要10s才返回
- 同步上下文执行 FuncAsync-中间部分1();
- 同步上下文执行 YAsync();//内部调用了Sleep10s, 要10s才返回
- 同步上下文执行 FuncAsync-中间部分2()
- 同步上下文执行 ZAsync();//内部调用了Sleep10s, 要10s才返回
- 同步上下文执行 FuncAsync-结束部分();
所以耗时时间还是30s
假设 XAsync(), YAsync(), YAsync()内部都把Sleep10s用Task.Run()都包起来返回
- 同步上下文执行 FuncAsync-开始部分();
- 同步上下文执行 XAsync(); 立刻返回, 在另一个线程执行Sleep(10)
- 同步上下文等待 但可以执行其他异步任务, 如果是Winform的话UI不会卡
- 后台线程10s结束告诉同步上下文继续执行
- 同步上下文执行 FuncAsync-中间部分1();
- 同步上下文执行 YAsync(); 立刻返回, 在另一个线程执行Sleep(10)
- 同步上下文等待 但可以执行其他异步任务, 如果是Winform的话UI不会卡
- 后台线程10s结束告诉同步上下文继续执行
- 同步上下文执行 FuncAsync-中间部分2()
- 同步上下文执行 ZAsync(); 立刻返回, 在另一个线程执行Sleep(10)
- 同步上下文等待 但可以执行其他异步任务, 如果是Winform的话UI不会卡
- 后台线程10s结束告诉同步上下文继续执行
- 同步上下文执行 FuncAsync-结束部分();
所以FuncAsync总耗时时间还是30s,优点是UI线程不会被卡住, UI线程不是被FuncAsync一个任务占有,其他异步任务也能在UI线程上执行,真正等待的任务都运行在后台线程。
下面这个版本,FuncAsync()执行的时间才是10s
async string FuncAsync()
{
var taskX = XAsync();
var taskY = YAsync();
var taskZ = ZAsync(); await Task.WhenAll(taskX, taskY, taskZ); return taskX.Result + taskY.Result + taskZ.Result;
}
如果在XAsync()里调用Task.Result同步等待会怎样?
- 同步上下文执行 FuncAsync-开始部分();
- 同步上下文执行 XAsync();
- XAsync() 调用 YAsync() 返回task
- YAsync() 开启后台线程sleep10s
- XAsync()等待task.Result
- XAsync() 调用 YAsync() 返回task
- 后台线程10s结束告诉同步上下文继续
XAsync要等待的结果(task.Result),需要同步上下文返回,
虽然后台线程已经同步上下文结果了,但同步上下文此时却还在执行XAsync的过程中.
互相等待,于是产生死锁.
举个形象的例子:
- 医生Doctor给病人Patients看病, 病人必须先排队,按次序来。
- 轮到某个病人PatientX时要某项检查报告,病人说,等我一下,检查报告在我老婆手里,我打电话让她送来。
- 于是医生Doctor和病人PatientX开始等待, 左等右等不来。
- 其实几分钟后病人的老婆PatientXWife已经把检查报告送来了, 只不过她拿着检查报告在队列里等。
async/await的一些用法的更多相关文章
- js中回调函数,promise 以及 async/await 的对比用法 对比!!!
在编程项目中,我们常需要用到回调的做法来实现部分功能,那么在js中我们有哪些方法来实现回调的? 方法1:回调函数 首先要定义这个函数,然后才能利用回调函数来调用! login: function (f ...
- [.NET] 怎样使用 async & await 一步步将同步代码转换为异步编程
怎样使用 async & await 一步步将同步代码转换为异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6079707.html ...
- [.NET] 利用 async & await 进行异步 IO 操作
利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html 序 上次,博主 ...
- async/await,了解一下?
上一篇博客我们在现实使用和面试角度讲解了Promise(原文可参考<面向面试题和实际使用谈promise>),但是Promise 的方式虽然解决了 callback hell,但是这种方式 ...
- promise async await使用
1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...
- promise 进阶 —— async / await 结合 bluebird
一.背景 1.Node.js 异步控制 在之前写的 callback vs async.js vs promise vs async / await 里,我介绍了 ES6 的 promise 和 ES ...
- javascript异步编程 Async/await
Async/await Async/await 在学习他之前应当补充一定的 promise 知识 它是一种与 promise 相配合的特殊语法,目前被认为是异步编程的终级解决方案 值得我们每一个人学习 ...
- async,await,Task 的一些用法
async,await,Task 的一些用法 private void Form1_Load(object sender, EventArgs e) { Display(); } public asy ...
- 异步操作之 Promise 和 Async await 用法进阶
ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 语法糖都可以更好解决多层回调问题, 详细用法可参考:https://www.cnblogs.com/cckui/p/99 ...
随机推荐
- Quartz教程一:使用quartz
原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...
- 【zzuli-2259】matrix
题目描述 在麦克雷的面前有N个数,以及一个R*C的矩阵.现在他的任务是从N个数中取出 R*C 个,并填入这个矩阵中.矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值.现 ...
- New Concept English three(20)
26w/m 36 In 1908 Lord Northcliffe offered a prize of £1000 to the first man who would fly across the ...
- device-independent bitmap (DIB) 设备无关位图
设备无关位图即独立于设备的位图(DIB)与"Device-Dependent Bitmaps (DDB) 设备相关位图"相比,它不再依赖于具体的设备,从而更适合在不同的计算机之间传 ...
- SpringMVC札集(03)——基于注解的SpringMVC入门完整详细示例
自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...
- 《Drools7.0.0.Final规则引擎教程》第4章 4.4 LHS简介&Pattern
LHS简介 在规则文件组成章节,我们已经了解了LHS的基本使用说明.LHS是规则条件部分的统称,由0个或多个条件元素组成.前面我们已经提到,如果没有条件元素那么默认就是true. 没有条件元素,官方示 ...
- How to choose the number oftopics/partitions in a Kafka cluster?
How to choose the number oftopics/partitions in a Kafka cluster? 如何为一个kafka集群选择topics/partitions的数量? ...
- EasyNVR网页/微信播放RTSP摄像机HLS/RTMP播放时出现起播等待问题的优化过程
EasyNVR 项目中, 我们需要在网页/微信中嵌入 HLS 播放器, 实现直播效果. 开发过程中, 我们调研了很多HLS播放器, 包括 百度cyberplayer, ckplayer, flowpl ...
- 不再为命名而苦恼!使用 MSTestEnhancer 单元测试扩展,写契约就够了
有没有觉得命名太难?有没有觉得单元测试的命名更难?没错,你不是一个人!看看这个你就知道了:程序员最头疼的事:命名 或它的英文原文 Don’t go into programming if you do ...
- NSURLSession学习笔记(二)Session Task
Session Task分为三种Data Task,Upload Task,Download Task.毫无疑问,Session Task是整个NSURLSession架构的核心目标. 下面写了一个简 ...