深入理解Async/Await
2017-03-01 08:00
597 查看
C# 5 Async/Await 语法特性,极大地简化了异步编程,但我们知道,异步编程的基本原理并没有发生根本改变。也就是说,当一些复杂的东西看起来很简单时,它通常意味着有一些有趣的事情在背后发生。在计算机程序设计语言领域,我们把这些本身很复杂但看起来很简单的语言特性称为语法糖,通常情况下,我们并不需要深入理解语法糖是怎么被一层一层包裹起来的,但是,最近我在使用.NET Core实现MySQL协议过程中,需要实现一个Awaitable Socket,所以我需要知道Async/Await背后到底发上了什么?
编译上面的C#代码,会出现
void
Task
Task
再修改一下代码,让编译器编译通过:
}}
使用ILSpy或者Reflector看看编译器干了什么:
上面的代码可以发现,aynce/await 代码被C#编译器重写了,编译器通过使用三个Builder和动态生成的StateMachine替换掉了我们的代码,而把我们的代码整理到StateMachine的
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
撇开这三个Builder的内部实现,从接口角度看,他们长得很像,我们只看看
C#编译器动态生成的StateMachine实现了
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
我们自己代码中的
[/code]
最后,借用《C# in Depth》作者Job Skeet的一句话与大家共勉:
I like knowing how a feature works before I go too far using it
我们团队正在招聘几个小伙伴【招聘】腾讯(深圳)新增招聘互联网金融.NET开发,我们是有追求的团队,不满足CRUD,我们探索.NET的深度技术,不仅仅是完成业务,我们追求极致,如果你也是这样,欢迎加入我们。
原文地址:http://www.xyting.org/2017/02/28/understand-async-await-in-depth.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
赞赏
人赞赏
编译器重写
我们通过写一个非常简单的控制台应用程序,一层一层地剥开C#编译器实现的 Async/Await 语法糖。namespace AsyncAwaitInDepth{ class Program { static void Main(string[] args){ } static async int Method() { return 1; } }}
编译上面的C#代码,会出现
CS1983 The return type of an async method must be void, Task or Task<T>错误,即编译器告诉我们,异步方法仅限于三个不同的返回类型︰
void
Task
Task
再修改一下代码,让编译器编译通过:
}}
使用ILSpy或者Reflector看看编译器干了什么:
上面的代码可以发现,aynce/await 代码被C#编译器重写了,编译器通过使用三个Builder和动态生成的StateMachine替换掉了我们的代码,而把我们的代码整理到StateMachine的
MoveNext()方法内部,三个Builder是:
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
撇开这三个Builder的内部实现,从接口角度看,他们长得很像,我们只看看
AsyncTaskMethodBuilder<T>接口:l
C#编译器动态生成的StateMachine实现了
IAsyncStateMachine接口:
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
我们自己代码中的
await Task.Delay(5);表达式,在StateMachine的
MoveNext()方法内部被替换成
awaiter = Task.Delay(5).GetAwaiter();,然后通过
IsCompleted属性判断是否需要启动一个新的线程去执行,最后通过
awaiter.GetResult();获取结果,或者是给Builder设置异常
builder.SetException(exception);
Awaitables and Awaiters
在.NET中,我们知道Xtable和Xter是一个一对的概念,比如IEnumerable<T>和
IEnumerator<T>,上面的代码,我们发现
Task,Task<TResult>是可以被awaited的,他们是awaitable,可以通过其
GetAwaiter()方法得到awaiter:
awaitable的
GetAwaiter()可以是实例方法,也可以是扩展方法。该方法返回的是一个awaiter,该awaiter必须实现
INotifyCompletion接口,可选实现
ICriticalNotifyCompletion接口,同时,必须提供一个名为
IsCompletedbool 属性, 必须提供
public TResult GetResult()方法。
[/code]
自定义awaitable和awaiter对象
我们费了那么大的劲,终于弄清楚了 Async/Await 背后到底发上了什么,做到了知其然知其所以然,因此,我们可以实现自己的awaitable和awaiter对象:最后,借用《C# in Depth》作者Job Skeet的一句话与大家共勉:
I like knowing how a feature works before I go too far using it
我们团队正在招聘几个小伙伴【招聘】腾讯(深圳)新增招聘互联网金融.NET开发,我们是有追求的团队,不满足CRUD,我们探索.NET的深度技术,不仅仅是完成业务,我们追求极致,如果你也是这样,欢迎加入我们。
原文地址:http://www.xyting.org/2017/02/28/understand-async-await-in-depth.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
赞赏
人赞赏
相关文章推荐
- 深入理解JavaScript的async/await
- 深入理解理解 JavaScript 的 async/await
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
- 深入理解ES7的async/await
- 深入理解 JavaScript 异步系列(5)—— async await
- 深入理解 JavaScript 异步系列(5)—— async await
- 深入理解ES7的async/await的用法
- 深入理解ES7的async/await
- 理解 JavaScript 的 async/await
- 关于 async 与 await的个人理解
- 快速理解和使用 ES7 await/async
- async和await理解代码
- 理解 async/await
- 理解 async/await
- 理解ES7中的async/await
- ES7前端异步玩法:async/await理解
- .Net 4.5 的async 和await 的简单理解使用
- Android入门:深入学习理解 Handler HandlerThread AsyncQueryHandler 三者的关系 收藏
- 理解 JavaScript 的 async/await
- 理解 JavaScript 的 async/await