本文版权归博客园和作者吴双本人共同所有。转载和爬虫必须在显要位置注明出处:http://www.cnblogs.com/tdws

半年前翻译了一系列很糟糕的异步编程文章,用异步的常用语来说:”在将来的某个时间“ 我还会重新翻译Async in C#5.0 http://www.cnblogs.com/tdws/p/5617242.html

 写在前面 

  

异步编程在处理并发方面被使用的越来越多,之所以说上面一句话,是为了区分多线程编程。各位司机都知道,实际上异步编程的核心目标正并发处理。可还是经常有一些让人感到很无奈的说法和问题,比如说,异步编程能提高应用性能吗?他能缩短我处理任务的时间吗?他阻塞线程吗?如果不阻塞线程,断点为什么不继续向下执行,我的哥!线程释放到哪儿去了?我都读书少你别骗我,线程都释放了程序怎么运行?前台我用了Ajax,后台使用Async有必要吗?也许如果作为司机的你看到最后一个问题,你只好摊手┑( ̄Д  ̄)┍。

 多线程场景理解

也许在某些时刻,你想提高应用程序执行速度,尽快拿到一个结果。这个时候,应该选择的绝对不是Async和Task。打个比方说,你和你老婆周末去超市购物,刚一进超市门你发现结账的每条队伍都几十人,于是你用到了多线程,你去排队,一个人一个人的往前走,你老婆在另一头抓紧购物,在你快走到收银台的时候,你老婆来把购物车推给了你,于是你们直接结账回家。虽然这种行为很不文明,但这就是多线程,和异步编程一点关系都没有。

 异步编程场景理解

那异步编程是什么情况,能解决什么问题呢?你和你老婆开了一家面包店,在初期只有你俩为顾客服务。没想到新店开张这么火,每分钟来一个顾客,而烤好一份面包需要两分钟。每来一位顾客你都拿着一片面包去后厨烤箱烤,并且你要和你老婆要花两分钟来等各自的烤箱完成任务。可是你等待的这两分钟,又来了两位顾客,着这样的速度下去,根本不能满足顾客们的需求呀!你已经发现你和你老婆的问题了:那就是你和你老婆这两条线程,都被烤箱花费的时间阻塞了!

你和你老婆为了解决阻塞的问题,又买了两台烤箱,并且为了避免新进顾客没人服务,每当你把面包送进烤箱后,标记其属于哪位顾客后立即返回,准备接待新的顾客,再有顾客光临,立马接待,并将新的面包送进另一个烤箱并标记,并立即返回等待为其他人服务。在面包烤好后,烤箱会以“叮”一声,注意在这一信号到达后,并不是一定要你去后厨烤箱取面包,而是你和你老婆谁不忙谁去取。这样处理后,高并发的顾客量,对你来说就显得得心应手了。你和你老婆做为两条线程,可以不断地以非阻塞的形式(不等烤箱),返回到顾客面前。但是需要注意的是不阻塞的概念,他不是让你的程序继续向下执行。就烤面包而言你的一个烤面包方法是这样的:

1.送入面包到烤箱 2.烤箱处理面包并给你结果 3.拿到面包送到顾客。所以说“不阻塞”的概念,不能让你直接做到第三步。在不阻塞期间,是没有线程在你的这个方法中的,这个方法还是要按照时间等待,等待在未来某个时刻的信号唤醒你或者你老婆,此时该方法恢复执行。所以说程序执行的时间依然不变,得到优化的是处理并发的能力,你店里(服务器)的吞吐量。

 看着代码理解

异步编程应当被适用于IO密集型场景,非CPU计算密集场景。大家知道线程受CPU调度,如果你是四核CPU,那么在你的线程池中,拥有四个线程,进程每个虚拟CPU分配一个线程的时候,性能表现会最棒。既能高效运用CPU,又不用来回切换上下文损耗性能。你想想,CPU密集的场景中,CPU就是要占用你的线程,在这个时候异步编程没有任何用处。然而在IO场景中,文件IO由win32用户模式的API到windows内核模式,在内核模式中操作磁盘驱动程序。这期间,你的线程阻塞在驱动程序的响应中。而异步编程中,你的操作通知到磁盘驱动程序后,线程立即返回而非等待,在将来的某个时刻,驱动程序处理结束,处理结果放入CLR线程池队列中,恢复状态机,线程池中任意线程取出结果,方法继续向下执行。在网络IO中也是如此,只不过驱动程序变成了网络驱动程序。请看如下代码:

public static async Task<string> DoSomeAsync()
{
using (var client = new HttpClient())
{
var result = await client.GetAsync(
"http://stackoverflow.com/questions/37991851/jenkins-configure-page-not-loading-version1-651-3-chrome-browser")
.Result.Content.ReadAsStringAsync();
Console.WriteLine(result);
//做一些其他操作
var res = + ;
//----------------
return "";
}
}

在编译的时候,DosomeAsync会被编译成一个状态机方法,状态机是什么先别管,你可以把它当成一个黑盒子。在遇到GetAsync的时候,在DoSomeAsync中返回一个Task任务对象,并由await在Task对象上传递用于恢复状态机的方法,相当于调用了ContinueWith().这个方法顾名思义,以xxx继续。然后线程从DoSomeAsync中返回。返回后干嘛去了?该线程可以去处理其他事情了。在将来某一时刻,服务器向我们发送了一个相应,网络驱动程序得知请求完毕,恢复该方法继续执行剩下的其他代码。配一张乱糟糟的图

 额外的好处

在GC的垃圾清理执行过程中,应用程序的所有线程都会被挂起,使用异步编程意味着在相同的并发量下,你可以使用更少的线程来完成处理,额外带来的好处就是,所需要清理的线程是更少的。还有一点就是,所使用的线程少了,CPU线程切换也变得更少。

如果我的点滴分享对你有点滴帮助,欢迎点击下方红色按钮关注,我将持续输出分享。也欢迎为我也为你自己点赞。

本文关键字,C# ASP.NET 异步编程 MVC Async await

额外阅读:异步编程最佳实践  https://msdn.microsoft.com/zh-cn/magazine/jj991977.aspx

让我们再为C#异步编程Async正名的更多相关文章

  1. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  2. 异步编程Async/await关键字

    异步编程Async \await 关键字在各编程语言中的发展(出现)纪实. 时间 语言版本 2012.08.15 C#5.0(VS2012) 2015.09.13 Python 3.5 2016.03 ...

  3. 抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext

    长话短说,本文带大家抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext 引言 C#异步编程语法糖async/await,使开发者很容易就能编写异步代码. ...

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

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

  5. 异步编程async/await

    什么是异步? 在异步程序中,程序代码不需要按照编写时的顺序严格执行,有时需要一在一个新的线程中运行一部分代码,有时无需创建新的 线程,但是为了更好的利用单个线程的能力,需要改变代码的执行顺序. 进程 ...

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

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

  7. .NetCore 异步编程 - async/await

    前言: 这段时间开始用.netcore做公司项目,发现前辈搭的框架通篇运用了异步编程方式,也就是async/await方式,作为一个刚接触的小白,自然不太明白其中原理,最重要的是,这个玩意如果不明白基 ...

  8. .net 温故知新:【5】异步编程 async await

    1.异步编程 异步编程是一项关键技术,可以直接处理多个核心上的阻塞 I/O 和并发操作. 通过 C#.Visual Basic 和 F# 中易于使用的语言级异步编程模型,.NET 可为应用和服务提供使 ...

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

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

随机推荐

  1. JavaScript之职责链模式

    一.概述 职责链模式(Chain of responsibility),就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有 ...

  2. IT持续集成之质量管理

    研发工具生态 质量相关工作 一次编译产出测试包与上线包 !从源头保证版本的⼀一致性!代码质量控制! 全⽅方位的⾃自动化测试体系保证! 提测冒烟效率! 全⾃自动上线流程杜绝⼈人⼯工犯错! 生产环境应⽤用 ...

  3. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  4. 在开源中国(oschina)git中新建标签(tags)

    我今天提交代码到主干上面,本来想打个标签(tags)的. 因为我以前新建过标签(tags),但是我现在新建的时候不知道入库在哪了.怎么找也找不到了. 从网上找资料也没有,找客服没有人理我,看到一个交流 ...

  5. IIS8 使用FastCGI配置PHP环境支持 过程详解

    平时帮朋友们配置过一些PHP环境的服务器,但是一直使用的都是Apache HTTP+PHP,今天呢,我吧IIS+PHP配置方式给大家发一下下~呵呵. 在这里,我使用的是FastCGI模块映射的方式配置 ...

  6. NodeJS使用mysql

    1.环境准备 手动添加数据库依赖: 在package.json的dependencies中新增, "mysql" : "latest", { "nam ...

  7. 安装并使用PHPunit

    安装并使用PHPunit Linux 下安装PHPunit PHP 档案包 (PHAR)  要获取 PHPUnit,最简单的方法是下载 PHPUnit 的 PHP 档案包 (PHAR),它将 PHPU ...

  8. (转载) RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  9. Linux硬件IO的优化简介

    Linux硬件IO的优化简介 首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的 ...

  10. Mono产品生命周期

    软件生命周期 同任何事物一样,一个软件产品或软件系统也要经历孕育.诞生.成长.成熟.衰亡等阶段,一般称为软件生命周期(软件生存周期) .软件生命周期模型是指人们为开发更好的软件而归纳总结的软件生命周期 ...