之前研究过c#的async和await关键字,幕后干了什么,但是不知道为什么找不到相关资料了。现在重新研究一遍,顺便记录下来,方便以后查阅。

基础知识

async 关键字标注一个方法,该方法返回值是一个Task、或者Task<TResult>、void、包含GetAwaiter方法的类型。该方法通常包含一个await表达式。该表达式标注一个点,将被某个异步方法回跳到该点。并且,当前函数执行到该点,将立刻返回控制权给调用方。

以上描述了async方法想干的事情,至于如何实现,这里就不涉猎了。

个人见解

由此可以知道,async 和await关键字主要目的是为了控制异步线程的同步,让一个异步过程,表现得好像同步过程一样。

比如async 方法分n个任务去下载网页并进行处理:先await下载,然后立刻返回调用方,之后的处理就由异步线程完成下载后调用。这时候调用方可以继续执行它的任务,不过,如果调用方立刻就需要async的结果,那么应该就只能等待,不过大多数情况:他暂时不需要这个结果,那么就可以并行处理这些代码。

可见,并行性体现在await 上,如果await 点和最终的数据结果距离越远,那么并行度就越高。如果await的点越多,相信也会改善并行性。

资料显示,async 和await 关键字并不会创建线程,这是很关键的一点。他们只是创建了一个返回点,提供给需要他的线程使用。那么线程究竟是谁创建?注意await 表达式的组成,他需要一个Task,一个Task并不代表一定要创建线程,也可以是另一个async方法,但是层层包裹最里面的方法,很可能就是一个原生的Task,比如await Task.Run(()=>Thread.Sleep(0)); ,这个真正产生线程的语句,就会根据前面那些await点,逐个回调。

从这点来看,async 方法,未必就是一个异步方法,他在语义上更加贴近“非阻塞”, 当遇到阻塞操作,立刻用await定点返回,至于其他更深一层的解决手段,它就不关心了。这是程序员需要关心的,程序员需要用真正的创建线程代码,来完成异步操作(当然这一步可由库程序员完成)。

注意async的几个返回值类型,这代表了不同的使用场景。如果是void,说明客户端不关心数据同步问题,它只需要线程的控制权立刻返回。可以用在ui 等场合,如果是Task,客户端也不关心数据,但是它希望能够控制异步线程,这可能是对任务执行顺序有一定的要求。当然,最常见的是Task<TResult>。

综上,async和await并不是为了多任务而设计的,如果追求高并发,应该在async函数内部用Task好好设计一番。在使用async 和await的时候,只需要按照非阻塞的思路去编写代码就可以了,至于幕后怎么处理就交给真正的多线程代码创建者吧。

示范代码

        static async Task RunTaskAsync(int step){for(int i=0; i < step; i++){await Task.Run(()=>Thread.Sleep(tmloop));//点是静态的,依次执行Thread.Sleep(tm2);}Thread.Sleep(tm3);}//客户端Task tk= RunTaskAsync(step);Thread.Sleep(tm1);//这一段是并行的,取max(函数,代码段)最大时间tk.Wait( );//这里代表最终数据

为了达到高度并行,应该用真正的多线程代码:

        static async Task RunTaskByParallelAsync(int step){await Task.Run(()=>Parallel.For(0,step,s=>{loop(tmloop);loop(tm2);}));loop(tm3);}

并行编码方法

并行执行有几个方法,第一个是创建n个Task,一起启动。问题是怎么处理await点。每个task写一个await点是不行的,因为遇到第一个await就立刻返回,而不会开启所有任务并行执行。因此await不能随便放。那么如何为一组Task设定await点呢?可以通过Task.WhenAll 这个方法,他会等待一组Task执行完毕返回。

特定情况下,可以用Parallel.For 来开启一组任务,但是这个类并没有实现async模式,也就是它会阻塞当前线程,所以需要用一个Task来包裹它。

可见,非阻塞和并行不完全是一回事。

常见的异步方式async 和 await相关推荐

  1. 理解异步函数async和await的用法

    定义 async作为一个关键字放在函数前面,表示该函数是一个异步函数,异步函数意味着该函数的执行不会阻塞后面代码的执行:而 await 用于等待一个异步方法执行完成: async/await的作用就是 ...

  2. Flutter异步编程async与await的基本使用

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 异步编程常用于网络请求 ...

  3. vue中异步函数async和await的用法

    先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行. 写一个async 函数 as ...

  4. rust异步之async、await、future

    1. 简单的异步 async The most common way to run a Future is to .await it. When .await is called on a Futur ...

  5. Unity中的异步编程【1】—— Unity与async 、 await

    新手在Unity里写东西,一个方法的内容如果写复杂了,容易把Uinty写死,就会卡帧,用流行的话来总结就是:在Update里面活生生把天聊死了. 此外,如果新手才入门,不擅长使用消息.事件来进行异步的 ...

  6. Async和Await异步编程的原理

    1. 简介 从4.0版本开始.NET引入并行编程库,用户能够通过这个库快捷的开发并行计算和并行任务处理的程序.在4.5版本中.NET又引入了Async和Await两个新的关键字,在语言层面对并行编程给 ...

  7. [转]异步性能:了解 Async 和 Await 的成本

    原文地址:http://msdn.microsoft.com/zh-cn/magazine/hh456402.aspx 异步编程长时间以来一直都是那些技能高超.喜欢挑战自我的开发人员涉足的领域 - 这 ...

  8. 异步编程初探:async和await

    前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了 ...

  9. 学习笔记 --- 编码过程中常见的三种异步方式

    实际的编码过程中, 凡是涉及到网络通信的代码, 异步都是决不可缺少的. 那么什么是异步呢? 异步就是子线程, 异步通过开辟子线程来实现, 所以一提到异步就应该想到子线程. 即使不涉及网络通信, 异步也 ...

最新文章

  1. 2021年大数据Flink(四十五):​​​​​​扩展阅读 双流Join
  2. PNAS-2018-多年多点5千样本鉴定玉米根际可遗传微生物
  3. 开发日记 20210316
  4. [JS] - onmusewheel事件(兼容IE,FF,opera,safari,chrome)
  5. 9、C语言中sscanf使用及运算符优先级
  6. NLog日志写文件的一个性能问题
  7. Linux下显示当前目录下的全部目录或文件
  8. framebuffer驱动详解4——framebuffer驱动分析2(probe函数讲解)
  9. 同一个页面提交多个form表单方法(详细)
  10. OAuth认证原理及HTTP下的密码安全传输
  11. 六逻辑层次 职业规划案例_我如何在六个月内改变职业并找到了一名开发人员...
  12. 80211n标准建链速率计算
  13. ai一个线段多个箭头_「平面设计」Illustrator(AI)基础教学-第2章 绘制简单的图形...
  14. 教务系统自动评教_「四川大学教务处本科登陆系统」四川大学本科教务系统 - 一键评教 - seo实验室...
  15. 为何不能直接拷贝软件安装好的目录运行
  16. log4j2日志配置颜色
  17. 搭建 WordPress 博客教程(超详细)
  18. 写得太好了,大约《越狱》批评(发布)
  19. 直播带货app源码,实现直播连麦和PK
  20. linux 软件包kbd 位置,linux系统安装包的管理

热门文章

  1. revit java 接口_如何使用Revit API获取axis属性?
  2. 20220130---CTF WEB方向刷题WP-----网页初始index.php/robots.txt
  3. cocos cteator中tiled模式 用图集容易出线
  4. 【移动端debug-6】如何做一个App里的web调试小工具
  5. EF Code First 学习笔记:关系(转)
  6. Jmeter运行过程中如何让Fiddler同时可以抓获到服务器的应答报文
  7. 信息掩码游戏地图掩码相关(msk)
  8. Eclipse里如何指定目标JRE版本
  9. ASP.NET 获取MSN联系人列表
  10. MFC 类库结构 总结