Search⌘ K

Coroutine Context: Accessing and Creating Context

Understand how Kotlin CoroutineContext functions as a data holder passed from parent to child coroutines. Learn to access context in suspending functions and create custom contexts to control coroutine behavior.

So CoroutineContext is just a way to hold and pass data. By default, the parent passes its context to the child, one of the parent-child relationship effects. We say that the child inherits context from its parent.

package kotlinx.coroutines.app
import kotlinx.coroutines.*

fun CoroutineScope.log(msg: String) {
   val name = coroutineContext[CoroutineName]?.name
   println("[$name] $msg")
}

fun main() = runBlocking(CoroutineName("main")) {
   log("Started") // [main] Started
   val v1 = async {
       delay(500)
       log("Running async") // [main] Running async
       42
   }
   launch {
       delay(1000)
       log("Running launch") // [main] Running launch
   }
   log("The answer is ${v1.await()}")
   // [main] The answer is 42
}
Parent-child relationship

Each child might have a specific context defined in the argument. This context overrides the one from the parent.

package kotlinx.coroutines.app

import kotlinx.coroutines.*

fun CoroutineScope.log(msg: String) {
   val name = coroutineContext[CoroutineName]?.name
   println("[$name] $msg")
}

fun main() = runBlocking(CoroutineName("main")) {
   log("Started") // [main] Started
   val v1 = async(CoroutineName("c1")) {
       delay(500)
       log("Running async") // [c1] Running async
       42
   }
   launch(CoroutineName("c2")) {
       delay(1000)
       log("Running launch") // [c2] Running launch
   }
   log("The answer is ${v1.await()}")
   // [main] The answer is 42
}
Overriding

Here is a simplified formula to calculate a coroutine context.

defaultContext + parentContext + childContext

Since new elements always replace old ones with the same key, the child context always overrides elements with the same key from the parent context. The defaults are used only for keys ...