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 之异步编程的学习的更多相关文章

  1. 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]

    看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...

  2. 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...

  3. 使用Async和Await进行异步编程(C#版 适用于VS2015)

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  4. 使用Async和Await进行异步编程(C#版 适用于VS2015) z

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  5. Async和Await进行异步编程

    使用Async和Await进行异步编程(C#版 适用于VS2015) 你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很 ...

  6. 【C#复习总结】 Async 和 Await 的异步编程

    谈到异步,必然要说下阻塞,在知乎上看到了网友举的例子非常省动,在这里我引用下. 怎样理解阻塞非阻塞与同步异步的区别? 老张爱喝茶,废话不说,煮开水. 出场人物:老张,水壶两把(普通水壶,简称水壶:会响 ...

  7. 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  8. [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  9. Async 和 Await 的异步编程 资料汇总

    使用 Async 和 Await 的异步编程 https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120).aspx 异步程序中的控制流 ht ...

随机推荐

  1. C语言之归并排序

    即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列. 上代码: #include <stdio.h> #include <stdlib.h> #define m ...

  2. IOS常见的加密方法,常用的MD5和Base64

    iOS代码加密常用加密方式 iOS代码加密常用加密方式,常见的iOS代码加密常用加密方式算法包括MD5加密.AES加密.BASE64加密,三大算法iOS代码加密是如何进行加密的,且看下文 MD5 iO ...

  3. PHP变量的定义与相应的数据类型

    在PHP中,变量的定义和C语言定义的方法是类似的,但是在PHP中,变量使用起来就非常灵活,一个变量既可以做整型,也可以是浮点型,也可以是字符串或者字符类型,通通只要在变量名前面加一个$然后加上你的变量 ...

  4. javascript类和原型学习笔记

    js中类的所有实例对象都从同一个原型对象上继承属性.我们可以自己写一个对象创建的工厂方法来来"模拟"这种继承行为: //inherit()返回一个继承自原型对象p的属性的性对象 / ...

  5. 织云 Metis:看腾讯怎么做智能运维

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作为企业智能运维门户,业界早已关注织云的智能运维体系.我们很荣幸地宣布织云 Metis 智能运维体系正式发布.自此,织云家族已发布:织云企业 ...

  6. apt-get Ubuntu本地ISO镜像入源

    转自http://blog.csdn.net/binchel/article/details/21486999 在没有网络的情况下,本地镜像源不实为一个上等的权宜之计! 目前linux的两大主流包管理 ...

  7. nodejs--(一)http模板篇

    Nodejs http模块可以创建服务器应用实例,也能发送http请求 1.http.get(options[, callback]) 发送简单Get请求,并响应 var http=require(' ...

  8. MQ队列管理器搭建(二)

    MQ级联方式使用场景 使用场景:     如上图所示,Application1与Application2要进行通信或者消息互换,使用MQ中间件作为中介.上图中,Application1与Applica ...

  9. 2018国赛 - Writeup(待补充)

    10.0.0.55 Writeup Web 0x01 easyweb 解题思路 题目很脑洞 用户名admin 密码123456进去可得到flag(密码现在换了) 解题脚本 无 Reverse 0x02 ...

  10. Mybatis与Ibatis比较

    随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis  虽然从正式版发布至今也有近一年时间,官方也非常友好的提供了中文版的使用手册,不过相信很多人还在项目中使用iba ...