本文版权归博客园和作者吴双本人共同所有。转载和爬虫必须在显要位置注明出处: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. Git命令总结

    本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...

  2. 如何在网页中提取Email地址

    开博好久了,今天第一次发表技术文档,之前总是将一些好的事例保存在电脑,时间久了找起来也很麻烦,所以还是放在博客里进行归类比较方便,这样也能将自己在学习过程中的一些心得体会分享给大家,也能给需要的人一点 ...

  3. CSS知识总结(八)

    CSS常用样式 8.变形样式 改变元素的大小,透明,旋转角度,扭曲度等. transform : none | <transform-function> <transform-fun ...

  4. 编写高质量代码:改善Java程序的151个建议(第8章:异常___建议114~117)

    建议114:不要在构造函数中抛出异常 Java异常的机制有三种: Error类及其子类表示的是错误,它是不需要程序员处理也不能处理的异常,比如VirtualMachineError虚拟机错误,Thre ...

  5. BridgePattern(桥接模式)

    /** * 桥接模式 * @author TMAC-J * 应用于多维度方案 * 用组合的形式代替继承 * 符合单一职责原则 * 一个类只有一个引起他变化的原因 * 增加程序灵活性 */ public ...

  6. Zephyr OS 简介

    最新发布的开源 Zephyr Project™(Zephyr 项目)是一款小型且可伸缩的实时操作系统,尤其适用于资源受限的系统,可支持多种架构:该系统高度开源,对于开发人员社区完全开放,开发人员可根据 ...

  7. Python 黑帽编程大纲(变化中)

    Python 黑帽编程大纲(预览版) 教程说明: 本系列教程,采用的大纲母本为<Understanding Network Hacks Attack and Defense with Pytho ...

  8. LeetCode-2AddTwoNumbers(C#)

    # 题目 2. Add Two Numbers You are given two linked lists representing two non-negative numbers. The di ...

  9. 三、Redis基本操作——List

    小喵的唠叨话:前面我们介绍了Redis的string的数据结构的原理和操作.当时我们提到Redis的键值对不仅仅是字符串.而这次我们就要介绍Redis的第二个数据结构了,List(链表).由于List ...

  10. ASP.NET中Session的sessionState 4种mode模式

    1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...