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;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;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,多么尴尬的一函数

你要知道多线程是干啥的。

把可以异步的耗时长的部分使用第二个线程去运行,减少对主线程的影响,保持应用响应、交互

async与await详解的更多相关文章

  1. async和await详解

     async和await详解 1.非UI线程中执行 Test()函数带有async 和await ,返回值写成Task. 1 using System; 2 using System.Threadin ...

  2. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  3. JavaScript中的async/await详解

    1.前言 ​ async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法.async和await关键字 ...

  4. C#多线程和异步(二)——Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  5. C#多线程和异步(二)——Task和async/await详解(转载)

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  6. 关于async function(){ let res = await } 详解

    本文引自: https://www.jianshu.com/p/435a8b8cc7d3 async function fn(){ //表示异步,这个函数里面有异步任务 let result = aw ...

  7. Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  8. C#多线程和异步——Task和async/await详解

    阅读目录 一.什么是异步 二.Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 3 Task的延续操作(WhenAny/WhenAll/Cont ...

  9. async await详解

    async await本身就是promise + generator的语法糖. 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面 ...

随机推荐

  1. 【转】关于在.Net开发中使用Sqlite的版本选择问题

    如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不同了. SQLite的.NET开发包来自是System.D ...

  2. Win10《芒果TV》商店内测版更新至v3.1.6:率先支持Xbox One平台 - 参与反馈,赢取VIP奖励

    芒果TV For Win10商店内测版 v3.1.6 于2016年9月1日星期四下午正式登陆商店 主要是优化手机版视频下载相关设置.策略.风险提示,并升级兼容目标,率先支持Xbox One平台,覆盖更 ...

  3. Android零基础入门第47节:自动完成文本框AutoCompleteTextView

    原文:Android零基础入门第47节:自动完成文本框AutoCompleteTextView 上一期学习的Spinner的使用,掌握的怎么样?本期一起来学习AutoCompleteTextView的 ...

  4. sklearn中LinearRegression使用及源码解读

    sklearn中的LinearRegression 函数原型:class sklearn.linear_model.LinearRegression(fit_intercept=True,normal ...

  5. ML:梯度下降(Gradient Descent)

    现在我们有了假设函数和评价假设准确性的方法,现在我们需要确定假设函数中的参数了,这就是梯度下降(gradient descent)的用武之地. 梯度下降算法 不断重复以下步骤,直到收敛(repeat ...

  6. Qt之Model-View架构(雨田哥的博客)

    Qt之Model-View架构 Qt之Model-View架构 简述 效果图 代码 结尾 简述 为什么会用这个模式,这里我就不解释了,可以看下 豆子哥的见解 .这里我只是如何去使用的.供大家共同探讨学 ...

  7. RSA der加密 p12解密以及配合AES使用详解

    在前面的文章中我有说过AES和RSA这两种加密方式,正好在前段时间再项目中有使用到,在这里再把这两种加密方式综合在一起写一下,具体到他们的使用,以及RSA各种加密文件的生成. 一: RSA各种加密相关 ...

  8. C++模板的理解与使用

    最近发现原来学的东西根本都不理解,所以本人正在恶补C++,把自己对C++中概念的最简单粗暴的理解写下来. 有问题的地方还请指出~随时更正 模板:顾名思义,就是为了方便以后使用而出现的东西,生活中的模板 ...

  9. 29 z-index

    这个东西非常简单,它有四大特性,每个特性你记住了,页面布局就不会出现找不到盒子的情况. z-index 值表示谁压着谁,数值大的压盖住数值小的, 只有定位了的元素,才能有z-index,也就是说,不管 ...

  10. Hexo+NexT(三):Next主题配置详解

    阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...