kotlin coroutines, what is the difference between coroutineScope and 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)

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.

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

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 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.

Leave a Comment