之前研究过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. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  2. .NET4.5 异步编程 async和await

    msdn介绍:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 其实很简单,标记了async的方法为异步方法,从方法的左大括号开始同步执行, ...

  3. C#异步编程(async and await)及异步方法同步调用

    1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库=异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...

  4. 彻底搞懂C#异步编程 async和await的原理

    1.前提 熟练掌握Task并行编程. 2.用Task并行解释async和await异步 因为控制台有多线程操作的优化,因此这里选择winform来做示例. 测试代码如下所示: 有三个textbox,一 ...

  5. 异步编程- async和await

    使用目的 避免阻塞主线程 提高程序响应能力 C#中使用 C# 中的 Async 和 Await 关键字是异步编程的核心. 疑惑 The async and await keywords don't c ...

  6. C#中的异步编程Async 和 Await

    谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...

  7. 令人清爽的异步函数async、await

    1.什么是async.await? async用于声明一个函数是异步的.而await从字面意思上是"等待"的意思,就是用于等待异步完成.并且await只能在async函数中使用; ...

  8. C#异步编程----async和await组合的写法

    微软示例: private async void StartButton_Click(object sender, RoutedEventArgs e) { // ExampleMethodAsync ...

  9. .net异步编程async和await的讨论收获

    微软官方描述: C# 5 引入了一种简便方法,即异步编程.此方法利用了 .NET Framework 4.5 及更高版本..NET Core 和 Windows 运行时中的异步支持. 编译器可执行开发 ...

随机推荐

  1. C#如何根据类的名词创建类的实例

    这个大概分为两种情况:1-在同一程序集访问该类:2-在不同的程序集访问 A:同一程序集,使用微软的创建对象的类:System.Activator: 先通过类名,获取到类型,在使用用于创建本地或远程对象 ...

  2. css常见的各种布局上(两列布局)

    常见的布局上(两列布局) 1.常见的两列布局 1.1左边固定,右边自适应,左边宽度已知,右边默认占满整行,使用left 左浮动,右边不浮动,设置margin-left:左侧宽度 <style&g ...

  3. Zabbix系统介绍

    监控概述 硬件监控 IPMI介绍文档:http://www.ibm.com/developerworks/cn/linux/l-ipmi/ 温度:使用ipmi对硬件温度,进行监控 硬盘:使用MegaC ...

  4. 【Oracle RAC】Linux系统Oracle11gR2 RAC安装配置详细过程V3.1(图文并茂)

    [Oracle RAC]Linux系统Oracle11gR2 RAC安装配置详细过程V3.1(图文并茂) 2 Oracle11gR2 RAC数据库安装准备工作2.1 安装环境介绍2.2 数据库安装软件 ...

  5. Lenovo System x3650 设置管理接口地址

    1.开启服务器. 2.显示<F1> Setup提示后,按 F1.(此提示在屏幕上仅显示几秒钟.必须迅速按 F1.) 如果同时设置了开机密码和管理员密码,则必须输入管理员密码才能访问完整的 ...

  6. 迷茫<第四篇:这两年>

    时间匆匆而过,不知不觉已经是到北京的第二个年头,又到年末,2017年接近了尾声,提前预祝各位看官元旦节快乐! 今年3月份跳槽了一次,4月份以高级开发工程师职位进来现在的公司一直工作到现在,没有以前那么 ...

  7. Use Wait & Notify to Implement Two Threads Run Alternatively

    public class ThreadCommunication { public static void main(String[] args) { Business business = new ...

  8. Linux下单机实现Zookeeper集群

    安装配置JAVA开发环境 下载ZOOKEEPER zookeeper下载地址 在下载的zookeeper目录里创建3个文件,zk1,zk2,zk3,用于存放每个集群的数据文件. 并在三个目录下创建da ...

  9. Identity Server 4 - Hybrid Flow - Claims

    前一篇 Identity Server 4 - Hybrid Flow - MVC客户端身份验证: https://www.cnblogs.com/cgzl/p/9253667.html Claims ...

  10. .NET Core微服务之基于Steeltoe使用Hystrix熔断保护与监控

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 =>  Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...