理解:

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. MingW-v4.8.0+EDE-v13.04 配置使用C语言图形库

    From: http://www.cnblogs.com/killerlegend/p/3946768.html Author:KillerLegend Date:2014.8.30 MingW的配置 ...

  2. Codeforces 835E. The penguin's game

    http://codeforces.com/problemset/problem/835/E 题意: 这是一道交互题 有n个数,其中有2个y,n-2个x 每次你可以询问若干个数的异或和,从而得出y的位 ...

  3. bzoj千题计划231:bzoj1997: [Hnoi2010]Planar

    http://www.lydsy.com/JudgeOnline/problem.php?id=1997 如果两条边在环内相交,那么一定也在环外相交 所以环内相交的两条边,必须一条在环内,一条在环外 ...

  4. django2.0 官方中文文档地址

    django2.0 官方开始发布中文文档了,之前还想着一直翻译完成所有有必要的内容,想着可以省事一些了,打开以后看了一下,发现官方的中文文档还没翻译完成, 现在(2018-7-10)最新章节是是  编 ...

  5. html5 canvas旋转+缩放

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 20155222 2016-2017-2 《Java程序设计》第6周学习总结

    20155222 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 从应用程序的角度来看,如果要将数据从来源中取出,可以使用输入串流:如果要将数据写入目的地,可 ...

  7. 第8月第22天 python scrapy

    1. cd /Users/temp/Downloads/LagouSpider-master ls ls ls lagou/settings.py cat lagou/settings.py ls p ...

  8. [译]How To Use the Linux Auditing System on CentOS 7

    本文是How To Use the Linux Auditing System on CentOS 7的中文版,翻译不到之处,还请指出和多多包涵.本文并不会完全遵从原文的一些格式,而是加入自己学习的理 ...

  9. 【干货】SIFT-Workstation 下载与安装 不跳过每一个细节部分

    SIFT-Workstation.ova     下载地址https://digital-forensics.sans.org/community/download-sift-kit       ov ...

  10. Linux环境下段错误的产生原因及调试方法小结【转】

    转自:http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...