A coroutine scope gives coroutines a structured lifetime. Coroutines launched from a scope become part of its parent-child hierarchy, so the parent can track its work rather than requiring manual bookkeeping or awaits. This structure also supports cancellation of child work when its parent is cancelled. section 15.1 section 15.3
Use the suspending coroutineScope function to split one computation into concurrent pieces. It creates a nested scope, waits until all children complete, and returns the value produced by its block. Because it suspends, a caller such as computeSum must also be suspending. section 15.1.1 section 15.3
import kotlinx.coroutines.*
import kotlin.random.Random
import kotlin.time.Duration.Companion.milliseconds
suspend fun generateValue(): Int {
delay(500.milliseconds)
return Random.nextInt(0, 10)
}
suspend fun computeSum() { #1
log("Computing a sum...")
val sum = coroutineScope { #2
val a = async { generateValue() }
val b = async { generateValue() }
a.await() + b.await() #3
}
log("Sum is $sum")
}
fun main() = runBlocking {
computeSum()
}
// 0 [main @coroutine#1] Computing a sum...
// 532 [main @coroutine#1] Sum is 10
Two async children generate values concurrently; coroutineScope waits for both await calls and yields their sum before execution continues. section 15.1.1
Choose scopes by the lifetime and kind of work involved:
- Use coroutineScope for bounded concurrent work whose combined result is needed before the enclosing operation can continue. section 15.1.1
- Use the CoroutineScope constructor for a class-owned lifetime, then cancel that scope when the component stops; practical scopes commonly include a SupervisorJob. section 15.1.2
- Prefer an existing framework scope when its lifetime matches the work, such as viewModelScope for a screen or a Ktor request scope for request-bound work. section 15.2.9
- Avoid GlobalScope for ordinary application work because it breaks the parent hierarchy and can let work outlive its intended owner. section 15.1.3
Returning a concurrent result
A suspend function can use coroutineScope to start two async image loads, await both values, and return combineImages(...) as one structured operation. If the work belongs to a request instead, launching from that request's scope makes it cancel when the client disconnects. section 1.2.4 section 15.2.9
CoroutineScope and coroutineScope have similar names but different jobs. CoroutineScope creates a standalone scope immediately for a managed lifecycle; coroutineScope is a suspending nested scope for decomposing and completing a computation. Scope choice determines whether work ends with a component, request, application, or enclosing coroutine. section 15.1.2 section 15.2.9
