kotlin coroutines,coroutineScope和withContext有什么区别 [英] kotlin coroutines, what is the difference between coroutineScope and withContext

查看:841
本文介绍了kotlin coroutines,coroutineScope和withContext有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

withContext
suspend fun <T> withContext(
    context: CoroutineContext, 
    block: suspend CoroutineScope.() -> T
): T (source)
Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.

suspend fun <R> coroutineScope(
    block: suspend CoroutineScope.() -> R
): R (source)
Creates a CoroutineScope and calls the specified suspend block with this scope. The provided scope inherits its coroutineContext from the outer scope, but overrides the context’s Job.

withContext使用CoroutineContext,并且在所有子级完成后,两者似乎都是complete.

the withContext takes CoroutineContext, and both seems to be complete after all its children are complete.

在哪种情况下,应优先使用withContextcoroutineScope?

In what case the withContext or the coroutineScope should be preferred than the other?

例如:

suspend fun processAllPages() = withContext(Dispatchers.IO) { 
    // withContext waits for all children coroutines 
    launch { processPages(urls, collection) }
    launch { processPages(urls, collection2) }
    launch { processPages(urls, collection3) }
}

也可能是

suspend fun processAllPages() = coroutineScope { 
    // coroutineScope waits for all children coroutines 
    launch { processPages(urls, collection) }
    launch { processPages(urls, collection2) }
    launch { processPages(urls, collection3) }
}

两个processAllPages()都在做同样的事情吗?

are the both processAllPages() doing the same?

更新:请参见>为什么withContext等待完成儿童协程

推荐答案

coroutineScope通常是withContext的特例,您可以在其中传递当前上下文,从而避免任何上下文切换.从示意图上来说,

Formally, coroutineScope is a special case of withContext where you pass in the current context, avoiding any context switching. Schematically speaking,

coroutineScope ≡ withContext(this.coroutineContext)

由于切换上下文只是withContext的几个功能之一,因此这是一个合法的用例. withContext等待您在块中启动的所有协程完成.如果它们中的任何一个失败,它将自动取消所有其他协程,并且整个块将引发异常,但不会自动取消您从其调用的协程.

Since switching contexts is just one of several features of withContext, this is a legitimate use case. withContext waits for all the coroutines you start within the block to complete. If any of them fail, it will automatically cancel all the other coroutines and the whole block will throw an exception, but won't automatically cancel the coroutine you're calling it from.

无论何时需要这些功能而无需切换上下文,都应该始终选择coroutineScope,因为它可以更清楚地表明您的意图.

Whenever you need these features without needing to switch contexts, you should always prefer coroutineScope because it signals your intent much more clearly.

coroutineScope关于几个子协程的作用域生命周期.它用于将一个任务分解为多个并发子任务.您无法使用它更改上下文,因此它从当前上下文继承Dispatcher.通常,如果需要,每个子协程将指定不同的Dispatcher.

coroutineScope is about the scoped lifecycle of several sub-coroutines. It's used to decompose a task into several concurrent subtasks. You can't change the context with it, so it inherits the Dispatcher from the current context. Typically each sub-coroutine will specify a different Dispatcher if needed.

withContext通常不用于启动子协程,而是临时切换当前协程的上下文.它应在其代码块完成后立即完成(从1.3.2版开始,实际上仍在其文档中说明).它的主要用例是将较长的操作从事件循环线程(例如主GUI线程)转移到使用其自己的线程池的Dispatcher上.另一个用例是定义关键部分",在该部分中协程将不会对取消请求做出反应.

withContext is not typically used to start sub-coroutines, but to temporarily switch the context for the current coroutine. It should complete as soon as its code block completes (as of version 1.3.2, this is actually still stated in its documentation). Its primary use case is offloading a long operation from the event loop thread (such as the main GUI thread) to a Dispatcher that uses its own thread pool. Another use case is defining a "critical section" within which the coroutine won't react to cancellation requests.

这篇关于kotlin coroutines,coroutineScope和withContext有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆