async与await详解
async和await只是编译器功能。编译器会用Task类创建代码。如果不适用这两个关键字,也可以用C#4.0和Task类实现同样的功能,只是没有那么方便。
题主在概念上确实混淆的不行,但是确实async/await这个东西继承了我软从VB6开始的光荣传统(易学难精)。工作中确实没有碰到几个真正搞的明白的同事(轮子哥,I大这种论外)。
首先,题主需要搞明白一个概念,就是async不是函数声明的一部分。从调用者的角度来看,不存在async这个东西。
async是一个专门给编译器的提示,意思是该函数的实现可能会出现await。async并不是表明这个方法是异步方法,而是标明这个方法里有异步调用。至于为啥要有这个提示,而不是编译器发现函数实现里有await的时候就自动加上async标志,这是定义语言标准时的选择,C#(这个feature)的作者也许认为这样写让作者更明确的意识到自己在实现一个包含异步调用的函数。(我瞎猜的)
下面举两个例子
Task<int> DelayAndCalculate1(int a, int b) { return Task.Delay(1000).ContinueWith(t => a + b); } async Task<int> DelayAndCalculate2(int a, int b) { await Task.Delay(1000); return a + b; }
这两个函数(不算函数名的不同),在函数声明上是完全没有区别的。只是其中一个在实现中使用了await,所以C#语法要求我们必须在标示async。
从调用者的角度来看,这两个函数完全一致(而且行为也一致),都可以使用await关键词unwrap Task类型的返回值(其实这里有一个叫做GetAwaiter的约定,这里不展开说)。
另一个佐证就是interface的定义中不能写async,因为如上所述,async不是函数声明,而其实编译函数实现的提示。
&amp;lt;img src="https://pic2.zhimg.com/50/v2-9a4354b91340bde2391e5b6406c05eb2_hd.jpg" data-rawwidth="680" data-rawheight="221" class="origin_image zh-lightbox-thumb" width="680" data-original="https://pic2.zhimg.com/v2-9a4354b91340bde2391e5b6406c05eb2_r.jpg"&amp;gt;
最后回到题主的问题为啥有了async还要写await,其实真正重要的是await(和其他异步的实现,如例子中的DelayAndCalculate1),有没有async反而确实不重要。
那么可不可以如题主所说的设计一个语法糖,不需要写Task<int>而写async int呢?答案是当然可以这么设计,但这就只是单纯的让编译器自动把async int翻译成Task<int>而已,C#的作者单纯没有这么设计而已(因为这会使得函数的返回值和声明时不同,我个人也觉得这会导致更大的confusion)。因为一个返回Task<int>的函数,不只可以用来await,还有很多别的玩法,语言应该给予开发人员解开和不解开的自由。最简单的例子:
async Task<int> ComplexWorkFlow() { Task<int> task1 = DoTask1(); Task<int> task2 = DoTask2(); Task<int> task3 = DoTask3UseResultOfTask1(await task1); Task<int> task4 = DoTask4UseResultOfTask2(await task2); return await DoTask5(await task3, await task4); }
我用短短几行实现了一个相对复杂的工作流,task直接的dependency很明确的表达在代码里,并且task1和task2可以并行执行,task3和task4可以并行执行(事实上更好的写法可以让task1->task3完全并行与task2->task4)。核心思路就是只有当某个task的执行结果需要被使用的时候才解开这个task的值(等它执行完毕)。
我觉得题主你没搞清楚多线程和异步的概念。
对应不同的需求,有很多种多线程执行方法的。async/await只是其中的一种,这种方法叫做异步调用。举个栗子吧,你的老板让你搬走一千箱货,你叫来一千个民工每人搬1箱,不管他搬没搬到指定地点,这个是Task.Run()。你让人搬到指定地点领根签子回来找你领钱,这个就是async/await。为啥要await?因为你要等着收回签子发钱啊,把应发的钱发完这事才算完呢。如果你只需一声令下:搬走!然后就可以拍拍屁股走人的话,就不要和人说什么要领签子回来换钱的话嘛。
因为这个函数你是想要在中途出现异步的,就是在await的地方创建新线程继续执行往后的代码,旧线程返回回去干该干的事去
结果你这函数里没有await,多么尴尬的一函数
你要知道多线程是干啥的。
把可以异步的耗时长的部分使用第二个线程去运行,减少对主线程的影响,保持应用响应、交互
转载于:https://www.cnblogs.com/kdp0213/p/8776956.html
async与await详解相关推荐
- async、await详解
一.async/await是什么? 简而言之, async用于申明一个function是异步的: 而await则可以认为是 async await的简写形式,是等待一个异步方法执行完成的. 二.asy ...
- C# Task和async/await详解
C# Task和async/await详解 什么是异步 Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 1 Thread阻塞线程的方法 2 T ...
- async与awite详解
async与awite详解 使用async与awite的目的:使用async和await能够使我们的异步代码书写,更像是在使用 同步代码那样,不会出现层层嵌套 注:promise类型对象有两个值,[[ ...
- Task和async/await详解
一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...
- C#多线程和异步(二)——Task和async/await详解
一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...
- 【转】Task和async/await详解
一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...
- C#多线程和异步(二)——Task和async/await详解(转载)
一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...
- async/await 详解
背景 promise的出现对于异步编程是一个跨越式的提高,但是往往在实际业务中存在很多更加复杂的流程,promise还是无法满足我们的需要,这时候在ES7中提出了async函数 概念 async 函数 ...
- async/await详解
最新文章
- 全网最全的Windows下Anaconda2 / Anaconda3里Python语言实现定时发送微信消息给好友或群里(图文详解)...
- 这26个阿里 Java 开源项目,你用过几个?
- 【ZZ】编程能力层次模型
- PHP 学习总结之变量
- Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意
- android api 相机,具有相机2 API的Android Lollipop上的ZSL功能
- 软件测试部分习题答案
- Sad Angel (悲伤的天使)-Игорь Крутой
- 【纯干货】Amoeba实现MySQL主从同步与读写分离
- 面试官:“你大学做过真实项目吗?”
- 从WINDOWS日志判断哪块硬盘好坏!!
- Leetcode每日一题:183.customers-who-never-order(从不订购的客户)
- hadoop-0.20.2完全分布式集群
- Nginx 系列:Nginx 实践,location 路径匹配
- 求二元一次方程 的解 C语言
- 怎么建立局域网_用ZeroTier搭建属于自己的虚拟局域网(VLAN)
- Python之爬虫和数据小解析
- 《城市化》(顾朝林)-重要术语
- 元数据管理-技术元数据解决方案
- 用计算机解决问题时 为什么要用计算思维,在亲历计算机解决问题的全过程中发展计算思维...