"job + UI" 上下文和使用 "parent = job" 有什么区别?

What's the difference between a "job + UI" context and using "parent = job"?

UI 协程指南包含有关如何管理 UI 协程生命周期的 section。它解释了我们应该创建一个顶级 Job 实例并将复合协程上下文 contextJob + UI 传递给我们启动的所有协程:

launch(contextJob + UI, block = block)

在我的项目中实施此模式时,我很自然地使用 contextJob 作为 父级

launch(UI, parent = contextJob, block = block)

我还没有测试行为上的差异,但我对这两个选项之间的语义差异很感兴趣。它们看起来与我非常相似,但我更愿意使用 parent = contextJob,因为它的作用更明显。具体来说,我注意到 parent 允许为 null,但如果我使用 +,我可能必须使用 NonCancellable 作为空对象。

使用 contextJob 作为 launchactorparent 参数有什么问题吗?

没有语义上的差异,以后也不会有。

使用+运算符的能力自然来自coroutineContext机器:Job是上下文元素,因此可以附加到上下文中。

但是写launch(UI + job)好像不自然,因为意图不明确。连接 UI 调度员和一些工作甚至意味着什么? 为了使这种模式可读,添加了 parent 参数,launch(UI, parent = job) 是一种更自然的方式,可以将启动作业的意图公开为给定 parent 的 child。 在引擎盖下,它仍然连接上下文和 parent,但现在 API 对用户来说看起来更漂亮了。

请注意,同样的方法可以用于其他图书馆的元素,例如对于 CoroutineExceptionHandler,但这是一个权衡:要么你有一个带有十几个默认参数的方法,要么牺牲可读性并编写 launch(ctx + myExceptionHandler),因此决定只引入 parent 参数作为最常见的一个。