理解:

1、async修饰的方法可理解为异步方法(必须要配合await,否则和普通方法无异)
2、当async方法执行遇到await,则立即将控制权转移到async方法的调用者
3、由调用者决定是否需要等待async方法执行完再继续往下执行
4、await会挂起当前方法,即阻塞当前方法继续往下执行,转交控制权给调用者

注意:如果调用一个async方 法,却不使用await关键字来标记一个挂起点的话,程序将会忽略async关键字并以同步的方式执行。编译器会对类似的问题发出警告。

例子一:(控制台程序)

         static void Main(string[] args)
{
MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
Console.Read();
}
static async void MyMain()
{
Console.WriteLine("main方法开始执行");
AsyncAction();
Console.WriteLine("main方法继续执行");
Console.WriteLine("main方法执行结束");
} static async Task<string> AsyncAction()
{
Console.WriteLine("AsyncAction方法await之前");
string result = await Task<string>.Run(() =>
{
Thread.Sleep();
Console.WriteLine("AsyncAction方法sleep一秒后");
return "AsyncAction的返回值";
});
Console.WriteLine("AsyncAction方法await之后-{0}", result);
return result;
}

执行结果:

由返回结果可以知,此异步方法AsyncAction执行遇到await,即程序执行到此行立刻被挂起,将控制权限交给MyMain方法,由MyMain决定是否等待AsyncAction执行完再往下执行,此处由于执行AsyncAction方法前不加await,所以直接往下执行。而AsyncAction方法中的await Task.Run(包括)后的代码会异步执行。

例子二:例子一中MyMain方法执行AsyncAction前面加await

         static void Main(string[] args)
{
MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
Console.Read();
}
static async void MyMain()
{
Console.WriteLine("main方法开始执行");
await AsyncAction();
Console.WriteLine("main方法继续执行");
Console.WriteLine("main方法执行结束");
} static async Task<string> AsyncAction()
{
Console.WriteLine("AsyncAction方法await之前");
string result = await Task<string>.Run(() =>
{
Thread.Sleep();
Console.WriteLine("AsyncAction方法sleep一秒后");
return "AsyncAction的返回值";
});
Console.WriteLine("AsyncAction方法await之后-{0}", result);
return result;
}

执行结果:

由于AsyncAction方法执行前加了await,故MyMain方法要等待其执行结束才继续往下执行。

使用场景及用法分析:

当有某一操作执行时间较长或者执行结果对整体程序执行影响不大(一般此操作都会是一个独立一个方法。)主线程的执行不依赖于此操作的执行结果。
常见于一些IO操作,如日志的记录,当触发记录日志动作的时候,应该让其独立一个线程去执行,此时不管日志记录成功与否,
都不应该阻塞主线程的执行。
在上面的例子一中,可以将AsyncAction方法中的 Task.Run 当成记录日志的动作,当程序执行到 await Task.Run后,
AsyncAction方法立刻被挂起,主线程MyMain继续往下执行。
这里可能有人会疑问?为何不直接在主线程MyMain中直接开启线程 Task.Run 来记录日志?
而是要定义到一个异步方法(此例子为AsyncAction方法)中处理日志。
是,如果此时只是为了记录日志,也不是必须要写到一个方法中。但是,
首先,这种单一功能的操作,本应该就是独立写到一个方法中。
其次是 AsyncAction方法 中的 await Task.Run 的返回值也许还有其他操作。

如下面例子:记录日志之前,需要获取登陆用户的一些信息,并且将用户信息一同保存到日志中,如果写到主线程MyMain中,则避免不了阻塞主线程(因为需要等待获取用户信息)。
当然,你也可以将这两个方法一起写到一个方法中由Task调用,这里只是举个例子来说明Async和await的用法场景。

         static void Main(string[] args)
{
MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
Console.Read();
}
static async void MyMain()
{
Console.WriteLine("main方法开始执行");
WriteUserLog();
Console.WriteLine("main方法继续执行");
Console.WriteLine("main方法执行结束");
} static async void WriteUserLog()
{
Console.WriteLine("获取用户信息之前");
string userInfo = await GetUserInfoAsync(); //尽量早的使用await,以便此方法尽快挂起(异步执行)
Console.WriteLine("写入日志之前");
WriteLog(userInfo);
} static Task<string> GetUserInfoAsync()
{
return Task.Factory.StartNew(() => {
Thread.Sleep();
Console.WriteLine("获取用户信息完成");
return "jxf";
});
} static void WriteLog(string userInfo)
{
Thread.Sleep();
Console.WriteLine("写入日志完成,用户信息:{0}", userInfo);
}

执行结果:

.net 中的async,await理解的更多相关文章

  1. 理解ES7中的async/await

    理解ES7中的async/await 优势是:就是解决多层异步回调的嵌套 从字面上理解 async/await, async是 "异步"的含义,await可以认为是 async w ...

  2. 理解C#中的 async await

    前言 一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解.(PS:文中涉及到了大量反编译源码,需要静下心来细细品味) 从简单开始 为了更容易理解 ...

  3. 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。

    [TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...

  4. 在现有代码中通过async/await实现并行

    在现有代码中通过async/await实现并行 一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色 ...

  5. ES7前端异步玩法:async/await理解 js原生API妙用(一)

    ES7前端异步玩法:async/await理解   在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是“异步”的意思,a ...

  6. [C#] .NET4.0中使用4.5中的 async/await 功能实现异

    好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...

  7. 在Silverlight中使用async/await

    现在 async/await 大行其道,确实,有了 async/await ,异步编程真是简单多了,个人觉得 async/await 的出现,给开发者还来的方便,绝不亚于当年 linq 的出现. 但要 ...

  8. [C#] .NET4.0中使用4.5中的 async/await 功能实现异步

    在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去 ...

  9. js循环中使用async/await踩过的坑

    最近写koa的时候遇见需要在循环中使用async/await的情况,当然第一反应就是直接上forEach,然后就直接翻车了... 直接上代码: function handleSql(val) { re ...

随机推荐

  1. Spark记录-spark与storm比对与选型(转载)

    大数据实时处理平台市场上产品众多,本文着重讨论spark与storm的比对,最后结合适用场景进行选型. 一.spark与storm的比较 比较点 Storm Spark Streaming 实时计算模 ...

  2. Spring RedisTemplate操作-哈希操作(3)

    @Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...

  3. [转载]AngularJS视图

    http://www.yiibai.com/angularjs/angularjs_views.html <html> <head> <title>Angular ...

  4. ie8下jquery改变PNG的opacity出现黑边

    复制网上的,没有他们那个类型的博客,所以就直接复制了 这些天在做一个效果,鼠标经过,PNG图片由透明变成不透明,jquery代 码:$(element).animate({"opacity& ...

  5. blockchain 名词解释

    1.UTXO UTXO是比特币交易的基本单位UTXO(Unspent Transaction Outputs)是未花费的交易输出,它是比特币交易生成及验证的一个核心概念.交易构成了一组链式结构,所有合 ...

  6. 2017/05/20 java 基础 随笔

    static 关键字的特点 1.随着类的加载而加载 2.优先于对象存在 3.被类的所有对象共享 如果某个成员变量是被所有对象共享的,那么他就应该定义为静态的 4.可以通过类名调用 其实它本身也可以通过 ...

  7. Ubuntu下pycharm安装

    参考:http://blog.csdn.net/langb2014/article/details/51166782 http://www.cnblogs.com/zhcncn/p/4027025.h ...

  8. java 异常匹配

    抛出异常的时候,异常处理系统会安装代码书写顺序找出"最近"的处理程序. 找到匹配的程序后,它就认为异常将得到清理,然后就不再继续查找. 查找的时候并不要求抛出的异常同处理程序的异常 ...

  9. java 内部类使用 .this 和 .new

    如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this,这样产生的引用自动地具有正确的类型,这一点在编译器就被知晓并受到检查,因此并没有运行时开销 //: innerclasses ...

  10. Centos7下yum安装zabbix-server的部署(一)

    一.环境准备 OS:CentOS 7.2 64bit Zabbix版本:3.0.12 MySQL版本:5.6 hostname ip 主机用途zabbix-server 10.0.0.44 服务端 z ...