本系列专栏#kotlin
到目前为止,本文已经结束。本文将介绍Coroutine结构汇编的原则。
在开始之前,我们可以回忆起Coroutine的结构性并发性与层次结构和结构并发,并且在上一篇文章中,该级别和结构是:
#压碎计划|结构化并发
这里有一个介绍。简而言之,父亲和儿子之间存在关系,而父亲的关系在这里我们使用手柄的Coroutine手柄来表明父亲的工作将有一个儿童变量来挽救他的儿子工作,以便您可以实现父亲工作。统一工作,Zi Job也取消了结构取消效应。
在Coroutine框架的中间级别概念中,CoroutinesCope是实现结构性并发的关键。实际上,从字面上的含义也可以理解。
实际上,越多,挤压整个Coroutine框架的知识以使知识形成系统的知识越容易。LET的评论启动Coroutine的2个API:启动和异步,下面的源代码:下面的源代码:
在这里发现它们都是Coroutinescope的所有扩展。为什么要设计为CoroutinesCope的扩展?如果不是这样设计的,那就不会意识到结构化关系吗?
实际上,在早期的Coroutine API中,这两个功能实际上不是CoroutinesCope的扩展。如果使用了早期API,则伪代码如下:
在这里,我们要实现结构化的并发。我们必须创建一个作业对象,然后将其作为参数传递到启动中,但是开发人员可能会忘记传输此参数,因此它将破坏结构化关系。
因此,CoroutinesCope旨在管理批处理处理,启动和异步被用作此类扩展的扩展功能,因此不会因忘记前面提到的参数而引起的非结构关系。
从以前的知识和API的迭代中,我们知道Coroutine中的真正控制Coroutine就是工作。该CoroutinesCope只是辅助效应。让我们看一下前面提到的父亲之间的关系。
在这里,我们编写以下示例代码:
在这里,我们创建了一个范围。在这里,我们查看此方法源代码:
可以发现CoroutinesCope()是顶级函数,而同一理论函数中的作业()也是顶级函数。这里还有一个小的知识点:当顶部级函数用作“构造函数”时,无法使用此功能的命名。使用驼峰命名方法,但从大写开始。
CoroutinesCope在这里返回。在上一篇文章中,我们知道这是Coroutinecontext的一揽子计划:
如果您不知道这些关系,则可以查看文章:
#压碎计划|Coroutinecontext
在这里,您可以通过上下文[作业]取出在上下文中保存的作业对象。如果没有工作,请创建一个作业对象并将其传递到上下文中。这个new是一个工作对象。
然后,我们继续阅读启动的源代码:
注1的代码在上一篇文章中所说。实际上,它是为新的Coroutine创建上下文,创建新上下文的方式也非常简单,也就是说,添加当前范围上下文以及参数传递的上下文。
注3的代码是Coroutine的启动。我们还在上一篇文章中说。这里没有提到这里的评论2,这是本章的关键。
注2这里涉及的两个类是:
可以发现,独立的核心是AbstractCoroutine的子类。在上一篇文章中,我们说这可以被视为一个抽象类,可以被视为代表性的Coroutine。当调用其构造函数时,第二个参数initparentjob参数始终是正确的,但实际上代表了表示形式。在建立coroutine之后,需要初始化最初的coroutine的父亲关系。
构造函数如下:
可以发现,AbstractCoroutine实际上是Jobsupport的子类,在这里我们可以从Initparentjob参数的前部知道,这里必须是正确的,也就是说,父亲-son关系的初始化,initarentjob()函数定义了在Jobsupport类中:
在这里,我们将简要分析:
因此,我们可以将Coroutine视为n叉树,每个公司都对应一个工作对象,每个工作都可以有一个父亲的工作和多个工作。
由于作业的关系如上图所示,因此结构化取消实际上是事件传输。当工作收到取消事件时,需要将其上级通知。
我们可以想象,其取消的代码应如下:
当然,这只是一个简化的伪代码。真正的代码更为复杂,但是原理是相似的。
让我们看一下范围取消代码:
在这里,您将调用作业的cancel()方法,并且此方法已在Jobsupport类中实现:
这是job.cancel()最终将调用cancelimpl方法。这是一个OnCancelComplete属性。实际上,当前的工作是否具有执行的合伙人。我们在上一个示例代码中的作业代码是手动创建的,因此无需执行任何关联。Cheng代码,因此它将转到代码的注释1部分:
继续分析:
这里的代码调用更为复杂。我们最终可以称呼通知法。这是最关键的代码。
让我们看一下这种方法:
此方法基本上与我们之前提到的假代码逻辑相同。让我们看一下逻辑:
这是新工作的数量,被取消的案件通过。Invoke()此处将最终调用儿童插曲的Invoke()方法:
在这里,代码最终将调用cancelimpl()方法,即,取消作业的作业的导入函数,实际上等同于递归调用。
让我们看一下如何通知父亲的工作:
请注意,评论1的返回值是有意义的。代表父亲的真实归来 - 律师事务所的例外和虚假的返回,这意味着父母验尸官没有处理异常。
在这里,我们发现,当异常是comcellationException时,将经过专门处理Coroutine。从总体上讲,父级Coroutine将忽略子核心的异常。当其他异常情况下,父级Coroutine将响应Sub -coroutine的取消。这次,您将致电cancelimpl()继续递归调用父级Coroutine的取消功能。
本文涉及很多代码跳跃,我们做了一个摘要:
在这里,我们可以进一步总结Coroutine结构的规则。
对于取消exception引起的取消,它只会散布并取消子库托恩;对于其他异常取消,可以向上或向下取消,这最终将导致所有coroutines被取消。
原始:https://juejin.cn/post/7096291855653928991