重新认识 Async/Await 语法糖

2023-02-05 0 386

提出诉讼.NET中的async/await,坚信许多人第三化学反应单厢是促发器程式设计,其实质是句法糖、但继续查案下来,难道是句法糖,所以历经校对后,或者说的标识符是怎样的,怎样继续执行的?

带着这些疑点,透过网路上数据资料的查阅,能了解到校对后,是透过同时实现 IAsyncStateMachine 的两个自动机来同时实现的,博客园里天神Jeffcky 已经说得很确切了,半条命:

https://www.cnblogs.com/CreateMyself/p/5983208.html

前述科学知识对他们认知 async/await 十分重要,但并非责任编辑探讨的侧重项目,促发本栏写这首诗的本意是:

一、只有Task能被await吗,await后就一定是促发器继续执行吗?

标准答案总之并非,google了几圈后辨认出,当两个类能被await,要满足用户下列前提:

它要包涵 GetAwaiter() 方式(示例方式或是扩充方式) // 全自动划重点项目:扩充方式,精明的你是并非立刻很多价值观火光GetAwaiter() 回到awatier示例,因此这个示例包涵如下表所示前提:要同时实现 INotifyCompletion 或是 ICriticalNotifyCompletion USB要包涵 IsCompleted 公用特性要包涵 GetResult() 方式,回到void或是其他回到值

前述前提中INotifyCompletion USB重要信息如下表所示:

重新认识 Async/Await 语法糖

重点项目前述对模块 continuation 的说明:委派在操作方式顺利完成后初始化。该处遗留下来两个难题:在谁的操作方式顺利完成后初始化,是是不是初始化的?

先把前述难题放默默地,他们来自己写两个能被await的类,因此检视其间继续执行的次序以及与否存有缓存转换:

重新认识 Async/Await 语法糖

前述标识符中,CustomAwaitable 示例满足用户了可被await的所有前提,因此正常透过校对,运行后辨认出结果如下表所示:

PS D:gitawaitablesrc> dotnet run Begin main,thread id is 1 Get awatier,thread id is 1 Begin Invoke continuation action on completed,thread id is 1 Get result,thread id is 1 End main,result is 100,thread id is 1 End Invoke

根据前述日志,能看出:

1、继续执行其间缓存并未发生转换,所以当他们不假思索的回答 await/async 就是促发器程式设计时,至少是两个不太严谨的标准答案

2、最后继续执行日志 “End Invoke” 表明:continuation action 这个委派,根据前述初始化日志次序能大致认知为:校对器将await后的标识符封装为这个 action,在示例顺利完成后初始化OnCompleted方式继续执行了await 后的标识符(注:实际情况比较复杂,如果有多行await,会转换为两个自动机,具体参看文章开头给出的连接)。

二、了解前述科学知识后,所以他们常规所说的await Task促发器程式设计又是是不是回事呢?

1、先来看Task部分源码:

重新认识 Async/Await 语法糖

上述红框标识符显示,Task在GetAwaiter中创建了 TaskAwaiter对象,并将this传递。

2、再来看TaskAwaiter源码:

重新认识 Async/Await 语法糖
重新认识 Async/Await 语法糖

看到该处,有了前面的科学知识,他们会对await task有了更加深入的认知:

Task透过增加两个GetAwatier()函数,同时将自身传递给TaskAwaiter类来同时实现了await句法糖的支持,同时在继续执行时,初始化GetResult()函数的本质是透过 Task.Wait等待促发器缓存的继续执行顺利完成,然后透过回调进行后续的操作方式。

总结

责任编辑主要对 async/await 句法糖进行分析验证,同时透过对Task源码分析,更加深入的认知此句法糖本身的句法,坚信透过透过此文,对大家从多个角度去认知促发器程式设计有帮助,我自己也在不停的学习。

标识符示例地址:https://github.com/xBoo/awaitable

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务