2. 常见的异步模式主要有callbaks,listeners(一种观察者模式),promise,3
3. 实现异步编程有4种方法可供选择,这4种访求实际上也对应着4种异步调用的模式,分为“等待”和“回调”两大类。4
3.4. async/await这两个新增的关键字只是语法糖,编译后的代码不新建线程 5
1. 异步编程的发展历史
1.1. Thread
1.2. Task
返回值
Thead是不能返回值的,但是作为更高级的Task当然要弥补一下这个功能。
1. static void Main() {
2. // GetDayOfThisWeek 运行在另外一个线程中
3. var dayName = Task.Run<string>(() => { return GetDayOfThisWeek(); });
4. Console.WriteLine("今天是:{0}",dayName.Result);
5. }
1.3. Async await
不知道如何去处理了。那今天我们就来好好看看这两兄弟和他们的叔叔(Task)爷爷(Thread)们到底有什么区别和特点,本文将会对Thread 到 Task 再到 .NET 4.5的 async和 await,这三种方式下的并行编程作一个概括性的介绍包括:开启线程,线程结果返回,线程中止,线程中的异常处理等。
Task是默认会直接使用线程池,但是Thread不会。如果我们不使用Task,又想用线程池的话,可以使用ThreadPool类。
作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 汉字名:艾龙, EMAIL:1466519819@qq.com
转载请注明来源: http://blog.csdn.net/attilax
1.3.1. await 的原形
await后的的执行顺序
感谢 locus的指正, await 之后不会开启新的线程(await 从来不会开启新的线程),所以上面的图是有一点问题的。
await 不会开启新的线程,当前线程会一直往下走直到遇到真正的Async方法(比如说HttpClient.GetStringAsync),这个方法的内部会用Task.Run或者Task.Factory.StartNew 去开启线程。也就是如果方法不是.NET为我们提供的Async方法,我们需要自己创建Task,才会真正
await并不是针对于async的方法,而是针对async方法所返回给我们的Task,这也是为什么所有的async方法都必须返回给我们Task。所以我们同样可以在Task前面也加上await关键字,这样做实际上是告诉编译器我需要等这个Task的返回值或者等这个Task执行完毕之后才能继续往下走。
Task.GetAwait()方法会给我们返回一个awaitable的对象,通过调用这个对象的GetResult方法就会挂起主线程,当然也不是所有的情况都会挂起。还记得我们Task的特性么? 在一开始的时候就启动了另一个线程去执行这个Task,当我们调用它的结果的时候如果这个Task已经执行完毕,主线程是不用等待可以直接拿其结果的,如果没有执行完毕那主线程就得挂起等待了。
await 实质是在调用awaitable对象的GetResult方法
1. / 这里主线程会挂起等待,直到task执行完毕我们拿到返回结果
2. var result = task.GetAwaiter().GetResult();
3. // 这里不会挂起等待,因为task已经执行完了,我们可以直接拿到结果
4. var result2 = await task;
Java has a class called java.util.concurrent.Future which is equivalent to the C# Task class.
You can set off work on a java.util.concurrent.Executor object. There are many implementations but ForkJoinTask.fork() is worth a look if you hit thread limits as soon as you try this.
You will be given a Future when you start work. Your method will carry on running. When you need the result from your Future you call get() and it will block until the result is ready. This is similar to using the await keyword in C#.
2. 常见的异步模式主要有callbaks,listeners(一种观察者模式),promise,
listeners这也是一种常见的异步编程方式,如:
$elem.on('click',doClick);function doClick(){ //do something};
设计模式中将这种方式称之为命令模式。这种方式的好处是你可以注册多个事件,待事件触发时调用注册的函数。
Promise异步编程总结起来就是实现了thenable,说的更直白的一点就是我跟你是好朋友,我可能有事需要你帮忙,你随时候着吧,有需要我会第一时间通知你。你跟小王也是好哥们,并同样告诉你需要他帮忙,并第一时间通知他。当然你通知他是在我通知你以后。用伪代码表示:
myself(function(){ callXiaoLi(); }) .then(function(){ //我是小李,你喊我了,我就去喊小王 callXiaowang(); }) .then(function(){ console.log('我是小王'); });
then实现比较绕,需要解释一下,如:.then(xx).then()
每次.then时会生成一个新的promise对象, 就是说后一个then是注册给上一个promise对象的,其出发条件依赖于上一个.then时生成的promise。
如果上一个.then 最后返回结果是非promise对象(即没有then方法),则直接 resolve
如果上一个.then最后返回的结果是promise对象,那.then生成的promise必须依赖返回结果中的promise,及内层的 promise.then( ".then时生成的promise".resolve)
3. 实现异步编程有4种方法可供选择,这4种访求实际上也对应着4种异步调用的模式,分为“等待”和“回调”两大类。
3.1. APM
C# .NET最早出现的异步编程模式被称为APM(Asynchronous Programming Model)。这种模式主要由一对Begin/End开头的组成。BeginXXX方法用于启动一个耗时操作(需要异步执行的代码段)
3.2. EAP
在C# .NET第二个版本中,增加了一种新的异步编程模型EAP(Event-based Asynchronous Pattern),EAP模式的异步代码中,典型特征是一个Async结尾的方法和Completed结尾的事件。XXXCompleted事件将在异步处理完成时被触发,在事件的处理函数中可以操作异步方法的结果。往往在EAP代码中还会存在名为CancelAsync的方法用来取消异步操作,以及一个ProgressChenged结尾的事件用来汇报操作进度。通过这种方式支持取消和进度汇报也是EAP比APM更有优势的地方。通过后文TAP的介绍,你会发现EAP中取消机制没有可延续性,并且不是很通用
3.3. TAP & async/await
从.NET4.0开始新增了一个名为TPL的库主要负责异步和并行操作的处理,目标就是使异步和并发操作有个统一的操作界面。TPL库的核心是Task类,有了Task几乎不用像之前版本的异步和并发那样去和Thread等底层类打交道,作为使用者的我们只需要处理好Task,Task背后有一个名为的TaskScheduler的类来处理Task在Thread上的执行。可以这样说TaskScheduler和Task就是.NET4.0中异步和并发操作的基础,也是我们写代码时不二的选择。
3.4. async/await这两个新增的关键字只是语法糖,编译后的代码不新建线程
await 不会开启新的线程,当前线程会一直往下走直到遇到真正的Async方法(比如说HttpClient.GetStringAsync),这个方法的内部会用Task.Run或者Task.Factory.StartNew 去开启线程。也就是如果方法不是.NET为我们提供的Async方法,我们需要自己创建Task,才会真正的去创建线程。
4. 参考
async & await 的前世今生 - 51CTO.COM.htm
你所必须掌握的三种异步编程方法callbacks,listeners,promise_JavaScript_第七城市.htm
.NET异步编程总结----四种实现模式 - DebugLZQ - 博客园.htm