async 和 await 之异步编程的学习
async修改一个方法,表示其为异步方法。而await表示等待一个异步任务的执行。js方面,在es7中开始得以支持;而.net在c#5.0开始支持。本文章将分别简单介绍他们在js和.net中的基本用法。
一、在js中的实现
js中的异步,还是基于Promise实现的。没有Promise就办法谈异步了。并且await只能出现async修改的方法中;以及reject会触发catch(异常)。
class AsyncTest{
//simple example
async run(){
//按照顺序等待后输出
let one = await this.output("one", 1000);
console.log('output:' + one);
let two = await this.output("two", 3000);
console.log(two);
console.log('run.....');
}
//await and Promise.all difference
async runDiff(){
let one = this.output('diff one', 2000);
let two = this.output('diff two', 2000);
console.log( await two + await one ); //在2秒之后,两个都输出了,而不是各自都等待两秒
console.log('runDiff.....');
}
//Promise.all realize
runAll(){
let nowTime = new Date();
console.log('b:' + nowTime.toTimeString());
let array = ["a", "b", "c"];
let that = this;
array.forEach(async function(item){
console.log( await that.output(item, 2000) );//2秒后同时输出
});
let fn = async ()=>{
for(let item of array){
let v = await this.output(item, 2000);
console.log(v ); //分步骤两秒执行
}
}
fn.call(this);
}
premosFn(){
let nowTime = new Date();
console.log('b:' + nowTime.toTimeString());
let array = ["a", "b", "c"];
let that = this;
//promise.all
let preFn = async function(){
let promises = array.map(function(item){
return that.output(item,2000); //同时开启多个定时器
});
let r = await Promise.all(promises);
console.log(r.join(','));
}
preFn();
}
reject(){
let rejectFn = function(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
reject();
},2000);
});
}
let asyncReject = async function(){
try{
await rejectFn();
}catch( e) {
console.log('reject.....');
}
}
asyncReject();
}
output(log, time){
return new Promise(resolve=>{
setTimeout(()=>{
var nowTime = new Date();
resolve( nowTime.toTimeString() + ":" + log + "\r\n");
}, time);
});
}
}
方法说明如下:
- output:简单的输出方法,但返回了一Promise。
- run: 使用await来等待两次对output的执行
- runDiff:调用output时即创建promise。两个promise会同步执行
- runAll:多任务同步执行和按步骤执行的实现方法。也就是forEach和for方法体中使用await的区别
- premosFn: promise.all的使用。
- reject: promise的reject会触发await的异常。
二、在c#中的实现
C#中异常是通过Task来实现的,所以标记了async的方法,其方法体中都可以出现await,否则不可以。以及Task中抛出的异常,如果没有同步等待,则不能获取异常
public class AsyncDemo
{
private Task<string> Output(string val, int time)
{
return System.Threading.Tasks.Task.Run(() =>
{
System.Threading.Thread.Sleep(time * );
return (DateTime.Now.ToLongTimeString()) + ": " + val + "\r\n";
});
} public async System.Threading.Tasks.Task Run()
{
string oneVal = await Output("One", );
string twoVal = await Output("Two", );
System.Console.WriteLine("Run \r\n" + oneVal + " " + twoVal);
} public async System.Threading.Tasks.Task RunDiff()
{
Task<string> oneTask = Output("one", );
Task<string> twoTask = Output("two", );
string val = await oneTask + await twoTask;
System.Console.WriteLine("RunDiff \r\n" + val); } public async System.Threading.Tasks.Task RunAll()
{
System.Console.WriteLine("b:" + (DateTime.Now.ToLongTimeString())); string[] array = new string[] { "a", "b", "c" };
foreach(var item in array)
{
string v = await Output(item, );
System.Console.WriteLine(v);
}
} public async System.Threading.Tasks.Task PromiseFn()
{
System.Console.WriteLine("b:" + (DateTime.Now.ToLongTimeString())); string[] array = new string[] { "a", "b", "c" };
List<System.Threading.Tasks.Task<string>> tasks = new List<System.Threading.Tasks.Task<string>>();
foreach (var item in array)
{
tasks.Add(Output(item, ));
}
//waitAll返回值不能获取,他返回为void,而WhenAll则返回为一个Task(这个Task就有其列表值)
string[] r = await System.Threading.Tasks.Task.WhenAll(tasks.ToArray());
System.Console.WriteLine(string.Join(",",r));
} public async System.Threading.Tasks.Task Reject()
{
Func<System.Threading.Tasks.Task> func = async () =>
{
throw new Exception("custom...");
await Output("reject", );
};
await func();
}
}
调用代码如下:
AsyncDemo asyncDemo = new AsyncDemo();
asyncDemo.Run().Wait();
asyncDemo.RunDiff().Wait();
asyncDemo.RunAll().Wait();
asyncDemo.PromiseFn().Wait();
try
{
asyncDemo.Reject().Wait();
}catch(Exception e)
{
System.Console.WriteLine("reject ex");
}
上述代码就是Js的async和await在c#中的翻版实现。 其中每个异步方法的调用,都用到了Wait方法来进行同步等待。以获取到结果。而没有像Js中那么难以控制。尤其注意,async方法中异常的捕获。
三、两者的异同点
- js中的async方法的调用,是没有wait方法来等待结果的执行的,只能通过promise来监听执行结果
- c#中的async方法,由于推荐返回Task或者Task<T>,所以可以用Wait来等待执行结果,如果async方法返回为void,则与js类似。 C#中的下面示例方法的调用者捕获不了异常:
public async void Run()
{
string oneVal = await Output("One", );
string twoVal = await Output("Two", );
System.Console.WriteLine("Run" + oneVal + " " + twoVal);
} - c#中的Task可以异步方法的链式调用,即可将前一任务的执行结果作为第二任务的参数传入,当然js的Promise也完全是可以很轻松的实现:
System.Console.WriteLine("b:" + (DateTime.Now.ToLongTimeString()));
string[] array = new string[] { "a", "b", "c" };
var r = await this.Output(array.First(), ).ContinueWith((tsc) =>
{
string v = tsc.GetAwaiter().GetResult();
return this.Output(v + "", );
});
System.Console.WriteLine(r.Result);
async 和 await 之异步编程的学习的更多相关文章
- 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]
看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
- 使用Async和Await进行异步编程(C#版 适用于VS2015)
你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...
- 使用Async和Await进行异步编程(C#版 适用于VS2015) z
你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...
- Async和Await进行异步编程
使用Async和Await进行异步编程(C#版 适用于VS2015) 你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很 ...
- 【C#复习总结】 Async 和 Await 的异步编程
谈到异步,必然要说下阻塞,在知乎上看到了网友举的例子非常省动,在这里我引用下. 怎样理解阻塞非阻塞与同步异步的区别? 老张爱喝茶,废话不说,煮开水. 出场人物:老张,水壶两把(普通水壶,简称水壶:会响 ...
- 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单 async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...
- Async 和 Await 的异步编程 资料汇总
使用 Async 和 Await 的异步编程 https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120).aspx 异步程序中的控制流 ht ...
随机推荐
- sxoi爆炸祭
好吧,纯粹是去玩玩的,我这么一个弱省的蒟蒻,进队纯粹是开玩笑.... Day0 去五中试机,感觉电脑手感不错,打了半个线段树的板子才发现试机要在自己的电脑上试,然后我无奈的搬东西(从26号搬到2号), ...
- 代理网络中安装tomcat的注意事项
搭建J2EE开发环境的时候,tomcat怎么都没办法访问主页面.主要的问题就是Network Error (tcp_error) 百度了半天也没搞明白,最后没办法,打算重装tomcat,便对照完整的安 ...
- c#实例化继承类,必须对被继承类的程序集做引用
0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Culture=neutral, PublicKeyTo ...
- JNDI 使用
J2EE技术规范(一)——JNDI 分类: java 基础2012-12-02 20:05 1539人阅读 评论(14) 收藏 举报 学习Java,我们首先要掌握的就是十三种技术规范,我们接下来就一步 ...
- ThinkPHP5从零基础搭建CMS系统(二)
接上节,开启wamp集成环境,在浏览器地址栏输入http://localhost/cms/public,即可运行项目,但是这边域名太长,做一下处理. 注:需要查看tp5全部教程,请点击右侧thinkp ...
- Redis案例——商品秒杀,购物车
秒杀案例: <?php header("content-type:text/html;charset=utf-8"); $redis = new redis(); $resu ...
- 从GitHub中整理出来的15个最受欢迎的Python开源框架,你喜欢哪个
从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框架 Djang ...
- Spring结合log4j(slf4j)
maven依赖 <!-- slf4j (级联:log4j/slf4j-api) --> <dependency> <groupId> ...
- java数据库基本操作(sqlserver 2000为例)
一.环境搭建 1.下载对应数据库连接驱动包并引入. 2.如果在web中调用必须在tomcat中也放入对应的驱动包. 3.在jre的lib\ext中也加入对应的驱动包. 二.连接数据库 public s ...
- JDK及JRE目录结构
JDK文件结构及目录: c:\jdk1.7.0: JDK安装根目录,包括版权.许可证和READEME文件,还包含ser.zip记录Java平台档案. c:\jdk1.7.0\bin 包含在Java开发 ...