ET9中ETTask传递新的Context原理

ET9中ETTask传递新的Context原理

前言

每一个异步函数都会创建两个对象,
1个是当前异步函数返回值(ETTASK)对应的ETAsyncTaskMethodBuilder,通过这个类的静态方法Create创建返回,这个builder类中会有一个Task对象,用于当返回值返回;
2个是编译器为我们创建的对应的状态机对象。其中状态机对象包裹了当前异步函数的所有代码。
在这里插入图片描述

对应的源码
在这里插入图片描述
以及包裹的状态机代码:
在这里插入图片描述

一、ETTask传递上下文的关键代码

如上图中红框所示,只要在源码中调用了await,就会执行对应的ETAsyncTaskMethodBuilder的AwaitUnsafeOnCompleted函数,这里就是传递上下文的入口。在一个异步函数(父异步)中,每次await调用另外一个异步函数(称为子异步吧),都会获得这个子异步函数对应的builder中的Task,又是通过父异步函数的builder对象的AwaitUnsafeOnCompleted来实现的。所以此时可以拿到此时父异步函数builder中的Task的上下文对象,传递给AwaitUnsafeOnCompleted中的子异步函数builder返回的builder中的Task。
ET9中的源码:

public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine{this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);awaiter.UnsafeOnCompleted(this.iStateMachineWrap.MoveNext);if (awaiter is not IETTask task){return;}if (this.tcs.TaskType == TaskType.WithContext){task.SetContext(this.tcs.Context);return;}this.tcs.Context = task;}

可以看到获取当前tcs(也就是builder中的Task)的类型是附带有上下文的,那么就进行一次设置子Task的上下文设置,如果不是携带上下文,就把当前Task上下文设置为这个子Task,用于后续上下文传递。
SetContext这是个Task的扩展函数,内部是循环,设置当前Task的上下文同时,找到对应的子Task,如果子Task不存在,或者已经是附带上下文了,就返回。

while (true){if (task.TaskType == TaskType.ContextTask){((ETTask<object>)task).SetResult(context);break;}// cancellationToken传下去task.TaskType = TaskType.WithContext;object child = task.Context;task.Context = context;task = child as IETTask;if (task == null){break;} 传递到WithContext为止,因为可能这一层设置了新的contextif (task.TaskType == TaskType.WithContext){break;}}

通过上面的代码,就可以理解为,当前异步函数中,只要await了一个ETTask,那么就会把当前异步函数ETTask(由对应的builder创建的)的上下文,传递给这个ETTask(没有设置自己的上下文),无论这个ETTask是由新的异步函数创建返回的,还是我们手动ETTask.Create的。

二、GetContextAsync怎么获取到当前上下文的

有了上面的介绍,我们就能知道,ETTask的上下文如何进行传递的。那么在一个异步函数中,要获取当前异步函数的上下文,那么就可以await ETTaskHelper.GetContextAsync来获取。
源码如下:

public static async ETTask<T> GetContextAsync<T>() where T: class{ETTask<object> tcs = ETTask<object>.Create(true);tcs.TaskType = TaskType.ContextTask;object ret = await tcs;if (ret == null){return null;}return (T)ret;}

当一个异步函数await这个GetContextAsync,那么进入这个函数时,外层的异步函数的ETTask上下文就传递到这个异步函数中(强调一下,由这个异步函数对应的Builder的创建的ETTask中)。然后内部创建了一个ETTask,再一次Await,那么上下文就由builder的Task传递到内部这个创建的ETTask。
要注意的是,内部创建的ETTask类型是ContextTask,那么在await–>AwaitUnsafeOnCompleted->SetContext,最终调用到SetContext时,有如下代码:

			if (task.TaskType == TaskType.ContextTask){((ETTask<object>)task).SetResult(context);break;}

即立刻调用此ETTask的SetResult的结果为上下文,然后ETTask会调用callback(由AwaitUnsafeOnCompleted传给ETTask的,状态机的MoveNext委托),就会返回到GetContextAsync函数中,获取结果并返回,这个结果就是当前异步函数的上下文信息了。

总结

ET9作者猫大的创新以及设计能力确实强,新版的ETTask也确实牛逼,有了上下文确实能搞出很多花样了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/35495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea 自动生成序列化数字

目标&#xff1a;当类继承Serializable后自动生成序列化Uid 网上查了很多说勾选class without ‘serialVersionUID’ 但是我勾选没用 最后发现&#xff0c;我勾选的是Serialization issues里面的配置&#xff0c;要勾选的是JVM languages下的 如下图所示&#xff0c;记录一下…

技术干货|SimLab 电子产品热流体仿真

电子产品热仿真特点有哪些&#xff1f; 结构复杂&#xff0c;电子设备包含几十~上千个元器件 体积小&#xff0c;功率密度高、关注热敏感元器件 多种冷却方式&#xff0c;自然冷却、风扇冷却、液冷、热管等 多维度&#xff0c;芯片级&#xff0c;板级&#xff0c;系统级 单…

昇思25天学习打卡营第03天|张量Tensor

何为张量&#xff1f; 张量&#xff08;Tensor&#xff09;是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数&#xff0c;这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 &#x1d45b;维空间内&#xff0c;有  &#x1d45b;&a…

ppt模版免费下载网站大全

PPT是我们传达信息、分享知识、展示项目和进行商务沟通的重要工具。一个设计精美、布局合理的PPT不仅能吸引观众的注意力&#xff0c;还能有效提升演讲者的专业形象。PPT模版可以帮助我们高效制作出精美的PPT&#xff0c;下面小编就来和大家分享一些免费无需注册登录就可以直接…

Mysql进阶-索引-使用规则-索引失效情况二(or连接的条件、数据分布影响)

文章目录 1、or连接的条件1.1、展示 tb_user 索引1.2、查询 id10 or age231.3、执行计划 id10 or age231.4、给 age 创建 索引1.4、执行计划 phone17799990004 or age23 2、数据分布影响2.1、查询 tb_user2.2、查询 phone >177999900202.3、执行计划 phone >177999900202…

Python学习打卡:day17

day17 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day17121、Python 操作 MySQL 基础使用pymysql创建到 MySQL 的数据库链接执行 SQL 语句执行非查询性质的SQL语句执行查询性质的SQL语句 122、Pyth…

幻兽帕鲁Palworld樱花版本服务器一键开服联机

1、登录服务器&#xff08;百度莱卡云&#xff09; 1.1、第一次购买服务器会安装游戏端&#xff0c;大约5分钟左右&#xff0c;如果长时间处于安装状态请联系客服 2、在启动中调整游戏参数 2.1、重启服务器&#xff0c;等待running出现&#xff0c;或者运行时间变为灰色&#x…

Linux0.12内核源码解读(5)-head.s

大家好&#xff0c;我是呼噜噜&#xff0c;好久没有更新old linux了&#xff0c;本文接着上一篇文章图解CPU的实模式与保护模式&#xff0c;继续向着操作系统内核的世界前进&#xff0c;一起来看看heads.s as86 与GNU as 首先我们得了解一个事实&#xff0c;在Linux0.12内核源…

2024年6月27日 (周四) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 喜马拉雅下载工具: 字面意思 Steam国产“类8番”游戏《永恒逃脱&#xff1a;暗影城堡》…

【JD-GUI】MacOS 中使用Java反编译工具JD-GUI

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 开篇说明概念理解一、基础环境说明1.1 硬件环境1.2 软件环境 二、下载与安装2.1 选择对应版本2.2 解压运行排除异常&#xff1a;2.3 关于…

GuiLite C语言实现版本

简介 本项目是idea4good/GuiLite的C语言实现版本&#xff0c;基于2024-06-20节点的版本&#xff08;提交ID&#xff1a;e9c4b57&#xff09;。 本项目仓库&#xff1a;GuiLite_C 需求说明 作为芯片从业人员&#xff0c;国产芯片普遍资源有限&#xff08;ROM和RAM比较少-都是…

[Vulnhub] wallabysnightmare LFI+RCE+Irssi聊天服务RCE

信息收集 Server IP AddressOpening Ports192.168.8.105TCP:22,80,6667,60080 $ nmap -p- -sC -sV 192.168.8.105 --min-rate 1000 -Pn 基础Shell http://192.168.8.105/?page../../../../../etc/shadow 当再次尝试访问已经关闭 $ nmap -p- -sC -sV 192.168.8.105 --min-rat…

【PTA】7-1 网红点打卡攻略(C/C++)代码实现 反思

解题细节分析&#xff1a; 0.比较图的两种存储方法&#xff0c;通过邻接矩阵存储更便于查找给定两点之间的关系 1.注意理解清楚题义&#xff1a;“访问所有网红点”中所有不是指攻略中所有&#xff0c;而是存在的全部的网红点 代码见下&#xff1a;// 需要注明的是&#xff…

锦江丽笙酒店稳步拓局海内外酒店市场 签约及意向合作20个新项目

&#xff08;中国上海&#xff0c;2024年6月27日&#xff09;民族品牌的国际化发展已日趋成为推动经济和文化交流的重要力量。作为民族品牌与国际品牌的融合发展&#xff0c;锦江丽笙酒店顺应市场趋势有序推进旗下品牌矩阵的全面布局&#xff1b;2024年上半年&#xff0c;已达成…

简易深度学习(1)深入分析神经元及多层感知机

一、神经元 单个神经元结构其实可以认为是一个线性回归模型。例如下图中 该神经元输入为三个特征&#xff08;x1&#xff0c;x2&#xff0c;x3&#xff09;&#xff0c;为了方便理解&#xff0c;大家可以认为每条线上都有一个权重和特征对应&#xff08;w1&#xff0c;w2&…

从源码到上线:直播带货系统与短视频商城APP开发全流程

很多人问小编&#xff0c;一个完整的直播带货系统和短视频商城APP是如何从源码开发到最终上线的呢&#xff1f;今天&#xff0c;笔者将详细介绍这一全过程。 一、需求分析与规划 1.市场调研与需求分析&#xff1a;首先需要进行市场调研&#xff0c;了解当前市场的需求和竞争情…

入职必备-Git 2种方式拉取代码

【SSH方式】: 1.复制电子邮箱 2.git bash 打开窗口 ssh-keygen -t rsa -C liuchangprimecare.group 3.一路回车&#xff0c;然后查看C:\Users\LiuChang.ssh里面的文件 打开id_rsa.pub文件&#xff0c;复制代码 4.添加到GitLab的公钥输入框 5.然后 git clone gitgitlab.pr…

使用容器配置文件构建任意应用镜像_并将应用镜像推送到公共仓库共享_应用分享与启动---分布式云原生部署架构搭建012

上面我们编写好了应用,并且,安装好了redis 现在我们把应用打包成镜像. 以前是这样做的,不方便,因为需要在服务器上,安装jdk什么的,现在有了 镜像就不用,给服务器安装镜像什么的了 以后所有机器都安装docker以后,就直接运行就可以了 首先看一下,安装java应用,需要 用到openjd…

指纹浏览器是什么?跨境多账号安全如何保证?

随着电子商务的蓬勃发展&#xff0c;越来越多的商家选择开设多店来扩大经营规模。然而多店运营也带来了一系列的挑战&#xff0c;其中之一就是账号安全。 1. 了解反检测浏览器和代理服务器 在我们开始讨论如何有效地使用反检测浏览器之前&#xff0c;我们首先需要了解这两个工…

openlayer 我的标注功能

背景&#xff1a; 通过openlayer库&#xff0c;可以在地图上实现绘制点、线、面。 并把绘制的结果添加到我的标注的弹框。 我的标注功能&#xff0c;包括&#xff1a;我的标注查询结果的数据展示&#xff1b;添加分组&#xff1b;添加我的标注&#xff1b;编辑分组、删除分组&a…