.net 中的async,await理解

摘要:
然后立即将控制权转移给异步方法的调用方。3.调用者决定是否在继续执行之前等待异步方法完成执行。4.wait挂起当前方法,(控制台程序)1sstaticvoidMain(string[]args)2{3MyMain();5}6staticsyncvoidMyMain()7{8Console.WriteLine(“main方法开始执行”);

理解:

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

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

例子一:(控制台程序)

复制代码
 1         static void Main(string[] args)
 2         {
 3             MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
 4             Console.Read();
 5         }
 6         static async void MyMain()
 7         {
 8             Console.WriteLine("main方法开始执行");
 9             AsyncAction();
10             Console.WriteLine("main方法继续执行");
11             Console.WriteLine("main方法执行结束");
12         }
13 
14         static async Task<string> AsyncAction()
15         {
16             Console.WriteLine("AsyncAction方法await之前");
17             string result = await Task<string>.Run(() =>
18             {
19                 Thread.Sleep(1000);
20                 Console.WriteLine("AsyncAction方法sleep一秒后");
21                 return "AsyncAction的返回值";
22             });
23             Console.WriteLine("AsyncAction方法await之后-{0}", result);
24             return result;
25         }
复制代码

执行结果:.net 中的async,await理解第3张

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

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

复制代码
 1         static void Main(string[] args)
 2         {
 3             MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
 4             Console.Read();
 5         }
 6         static async void MyMain()
 7         {
 8             Console.WriteLine("main方法开始执行");
 9             await AsyncAction();
10             Console.WriteLine("main方法继续执行");
11             Console.WriteLine("main方法执行结束");
12         }
13 
14         static async Task<string> AsyncAction()
15         {
16             Console.WriteLine("AsyncAction方法await之前");
17             string result = await Task<string>.Run(() =>
18             {
19                 Thread.Sleep(1000);
20                 Console.WriteLine("AsyncAction方法sleep一秒后");
21                 return "AsyncAction的返回值";
22             });
23             Console.WriteLine("AsyncAction方法await之后-{0}", result);
24             return result;
25         }
复制代码

执行结果:.net 中的async,await理解第6张

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

使用场景及用法分析:

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

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

复制代码
 1         static void Main(string[] args)
 2         {
 3             MyMain();//由于main方法无法定义成async,顾此定义一个方法MyMain来表示main方法。
 4             Console.Read();
 5         }
 6         static async void MyMain()
 7         {
 8             Console.WriteLine("main方法开始执行");
 9             WriteUserLog();
10             Console.WriteLine("main方法继续执行");
11             Console.WriteLine("main方法执行结束");
12         }
13 
14         static async void WriteUserLog()
15         {
16             Console.WriteLine("获取用户信息之前");
17             string userInfo = await GetUserInfoAsync(); //尽量早的使用await,以便此方法尽快挂起(异步执行)
18             Console.WriteLine("写入日志之前");
19             WriteLog(userInfo);
20         }
21 
22         static Task<string> GetUserInfoAsync()
23         {
24             return Task.Factory.StartNew(() => {
25                 Thread.Sleep(1000);
26                 Console.WriteLine("获取用户信息完成");
27                 return "jxf";
28             });
29         }
30 
31         static void WriteLog(string userInfo)
32         {
33             Thread.Sleep(1000);
34             Console.WriteLine("写入日志完成,用户信息:{0}", userInfo);
35         }
复制代码

执行结果:.net 中的async,await理解第9张

免责声明:文章转载自《.net 中的async,await理解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Unity3D中抖屏(抖动相机)效果的简单实现教你高速高效接入SDK——Unity统一接入渠道SDK(Android篇)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pycha安装插件

pycharm安装插件 方法一: 有的插件不能下载 file-setting-plugins-搜索-Browse Repositories 方法二: https://plugins.jetbrains.com/搜索插件下载 file-setting-plugins -install选择下载好的压缩包即可 出现”Plugin 'Markdown suppo...

延时器 清除延时器

 // 定时器,延时器         // 定时器 : 根据时间间隔,循环往复执行程序,除非停止会一直执行程序 --有间隔的循环         // 延时器 : 根据时间间隔,延迟执行程序的时间,只会执行一次         --定时炸弹         // 语法: 时间单位 : 毫秒         // setTimeout(function(...

selenium 常见问题整理。

一:日期控件 selenium不能直接对日期控件操作,可以通过js对日期控件做赋值操作 WebElement inputTimeBox=driver.findElement(by.name("###"));                         //定位日期控件 Stringtime = "2015/10/10"; ((JavascriptExe...

CALayer 进阶

转载自:http://www.cofcool.net/development/2015/06/19/ios-study-note-eight-CALayer-info/ The CALayer class manages image-based content and allows you to perform animations on that con...

重写ResultSet实现分页功能(最好的分页技术)(转)

1.首先定义一个接口Pageable 继承ResultSet这个类 并在接口中定义一些自己的方法,具体方法如下:  package com.page; import java.sql.ResultSet; public interface Pageable extends ResultSet {   /**返回总页数 */ int getPageCount...

IOS开发—事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

触摸事件 在用户使用app过程中,会产生各种各样的事件 一、iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象” UIApplication、UIViewController、UIView都继承自UIRespond...