为什么 withContext 等待子协程的完成
Why does withContext await for the completion of child coroutines
documentation of withContext
状态
Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.
然而,实际行为是它也在等待所有子协程,并且不一定return块的结果而是在子协程中传播任何异常。
suspend fun main() {
try {
val result = withContext(coroutineContext) {
launch {
delay(1000L)
throw Exception("launched coroutine broke")
}
println("done launching")
42
}
println ("result: $result")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
我希望上面的代码打印 result: 42
,然后可能会打印来自子协程的未捕获异常。相反,它等待一秒钟然后打印 Error: launched coroutine broke
.
因此,实际行为与 coroutineScope
生成器的行为相匹配。虽然这可能是一种有用的行为,但我认为它与文档相矛盾。文档是否应更新为类似于 coroutineScope
?
的内容
This function returns as soon as the given block and all its children coroutines are completed.
此外,这是否意味着我们可以互换使用 coroutineScope
和 withContext(coroutineContext)
,唯一的区别是样板少一点?
withContext
创建了一个新工作。这意味着在内部启动的所有协程都是该作业的子级。它仅在作业完成时 returns。由于结构化并发,它仅在所有子协程也完成时才结束。
当任何子作业失败时,父作业将被取消。这也将取消所有其他子作业。由于withContext
returns一个结果,抛出异常
CoroutineScope
的 documentation 在这方面很有帮助:
Every coroutine builder (like launch, async, etc) and every scoping function (like coroutineScope, withContext, etc) provides its own scope with its own Job instance into the inner block of code it runs. By convention, they all wait for all the coroutines inside their block to complete before completing themselves, thus enforcing the discipline of structured concurrency.
我认为 withContext
的文档也可以改进。 Job
和 CoroutineContext
的文档非常有用,因为它们提供了更多 high-level 的观点。
Furthermore, does that mean that we can use coroutineScope and withContext(coroutineContext) interchangeably, the only difference being a bit less boilerplate?
是的,他们应该以同样的方式行事。不过,它们适用于不同的用例。
coroutineScope
旨在为多个并行协程提供一个范围,如果其中任何一个失败,所有并行协程都将被取消。
withContext
旨在用于切换给定代码块的上下文(例如 Dispatcher)。
Here 是我最近在 kotlin 讨论论坛上提出的一个类似问题。该线程包含更多类似的案例和进一步的见解。
documentation of withContext
状态
Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.
然而,实际行为是它也在等待所有子协程,并且不一定return块的结果而是在子协程中传播任何异常。
suspend fun main() {
try {
val result = withContext(coroutineContext) {
launch {
delay(1000L)
throw Exception("launched coroutine broke")
}
println("done launching")
42
}
println ("result: $result")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
我希望上面的代码打印 result: 42
,然后可能会打印来自子协程的未捕获异常。相反,它等待一秒钟然后打印 Error: launched coroutine broke
.
因此,实际行为与 coroutineScope
生成器的行为相匹配。虽然这可能是一种有用的行为,但我认为它与文档相矛盾。文档是否应更新为类似于 coroutineScope
?
This function returns as soon as the given block and all its children coroutines are completed.
此外,这是否意味着我们可以互换使用 coroutineScope
和 withContext(coroutineContext)
,唯一的区别是样板少一点?
withContext
创建了一个新工作。这意味着在内部启动的所有协程都是该作业的子级。它仅在作业完成时 returns。由于结构化并发,它仅在所有子协程也完成时才结束。
当任何子作业失败时,父作业将被取消。这也将取消所有其他子作业。由于withContext
returns一个结果,抛出异常
CoroutineScope
的 documentation 在这方面很有帮助:
Every coroutine builder (like launch, async, etc) and every scoping function (like coroutineScope, withContext, etc) provides its own scope with its own Job instance into the inner block of code it runs. By convention, they all wait for all the coroutines inside their block to complete before completing themselves, thus enforcing the discipline of structured concurrency.
我认为 withContext
的文档也可以改进。 Job
和 CoroutineContext
的文档非常有用,因为它们提供了更多 high-level 的观点。
Furthermore, does that mean that we can use coroutineScope and withContext(coroutineContext) interchangeably, the only difference being a bit less boilerplate?
是的,他们应该以同样的方式行事。不过,它们适用于不同的用例。
coroutineScope
旨在为多个并行协程提供一个范围,如果其中任何一个失败,所有并行协程都将被取消。
withContext
旨在用于切换给定代码块的上下文(例如 Dispatcher)。
Here 是我最近在 kotlin 讨论论坛上提出的一个类似问题。该线程包含更多类似的案例和进一步的见解。