.net 中的async,await理解
理解:
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理解的更多相关文章
- 理解ES7中的async/await
理解ES7中的async/await 优势是:就是解决多层异步回调的嵌套 从字面上理解 async/await, async是 "异步"的含义,await可以认为是 async w ...
- 理解C#中的 async await
前言 一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解.(PS:文中涉及到了大量反编译源码,需要静下心来细细品味) 从简单开始 为了更容易理解 ...
- 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。
[TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...
- 在现有代码中通过async/await实现并行
在现有代码中通过async/await实现并行 一项新技术或者一个新特性,只有你用它解决实际问题后,才能真正体会到它的魅力,真正理解它.也期待大家能够多分享解一些解决实际问题的内容. 在我们遭遇“黑色 ...
- ES7前端异步玩法:async/await理解 js原生API妙用(一)
ES7前端异步玩法:async/await理解 在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是“异步”的意思,a ...
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异
好东西需要分享 原文出自:http://www.itnose.net/detail/6091186.html 在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framew ...
- 在Silverlight中使用async/await
现在 async/await 大行其道,确实,有了 async/await ,异步编程真是简单多了,个人觉得 async/await 的出现,给开发者还来的方便,绝不亚于当年 linq 的出现. 但要 ...
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异步
在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去 ...
- js循环中使用async/await踩过的坑
最近写koa的时候遇见需要在循环中使用async/await的情况,当然第一反应就是直接上forEach,然后就直接翻车了... 直接上代码: function handleSql(val) { re ...
随机推荐
- Kafka 0.8 NIO通信机制
一.Kafka通信机制的整体结构 同时,这也是SEDA多线程模型. 对于broker来说,客户端连接数量有限,不会频繁新建大量连接.因此一个Acceptor thread线程处理新建连接绰绰有余. K ...
- 【Linux】MySQL安装及允许远程访问
安装环境/工具 Linux( centOS 版) MySQL(MySQL-5.6.28-1.el7.x86_64.rpm-bundle.tar版) 安装步骤 1.解压mysql安装文件 命令:tar ...
- bzoj千题计划287:bzoj1228: [SDOI2009]E&D
http://www.lydsy.com/JudgeOnline/problem.php?id=1228 打SG函数表,找规律: 若n是奇数m是奇数,则SG(n,m)=0 若n是偶数m是偶数,则SG( ...
- 20155220 2016-2017-2 《Java程序设计》第六周学习总结
20155220 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第十章 输入输出 10.1 InputStream OutputStream 数据有来源与目 ...
- 20155202 2016-2017-2 《Java程序设计》第5周学习总结
20155202 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章:异常处理 java中所有错误会包装成对象,可以尝试(try)执行程序并捕捉(catc ...
- 20155203 2016-2017-3 《Java程序设计》第5周学习总结
20155203 2016-2017-3 <Java程序设计>第5周学习总结 教材学习内容总结 课堂知识总结 封装是继承的基础,继承是多态的基础.多态是用父类声明对象的引用,用子类生成对象 ...
- Manacher's Algorithm 马拉车算法
作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 代码: #include<bit ...
- mysql内连接、左连接、右连接
内连接(INNER JOIN)(典型的连接运算,使用像 = 或 <> 之类的比较运算符).包括相等连接和自然连接. 内连接使用比较运算符根据每个表共有的列的值匹配两个表中的 ...
- Mysql导入脚本失败,提示需要SUPER权限
1.删除: /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ 2.查看增删函数有没有重复 3.删除: set GLOBAL log ...
- android 调用系统照相机拍照后保存到系统相册,在系统图库中能看到
需求: 调用系统照相机进行拍照,并且保存到系统相册,调用系统相册的时候能看到 系统相册的路径:String cameraPath= Environment.getExternalStorageD ...