Bird
Raised Fist0
Kotlinprogramming~20 mins

WithContext for dispatcher switching in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
WithContext Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this coroutine code using withContext?

Consider the following Kotlin coroutine code snippet. What will be printed to the console?

Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Start: ${Thread.currentThread().name}")
    withContext(Dispatchers.IO) {
        println("Inside IO: ${Thread.currentThread().name}")
    }
    println("End: ${Thread.currentThread().name}")
}
A
Start: main
Inside IO: DefaultDispatcher-worker-1
End: main
B
Start: main
Inside IO: main
End: main
C
Start: main
Inside IO: IO-thread
End: main
D
Start: main
Inside IO: DefaultDispatcher-worker-1
End: DefaultDispatcher-worker-1
Attempts:
2 left
💡 Hint

Remember that withContext(Dispatchers.IO) switches the coroutine context to a background thread pool.

❓ Predict Output
intermediate
2:00remaining
What happens if you use withContext with the same dispatcher?

What will be the output of this Kotlin coroutine code?

Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Before withContext: ${Thread.currentThread().name}")
    withContext(Dispatchers.Default) {
        println("Inside withContext: ${Thread.currentThread().name}")
    }
    println("After withContext: ${Thread.currentThread().name}")
}
A
Before withContext: main
Inside withContext: DefaultDispatcher-worker-1
After withContext: main
B
Before withContext: main
Inside withContext: main
After withContext: main
C
Before withContext: DefaultDispatcher-worker-1
Inside withContext: DefaultDispatcher-worker-1
After withContext: DefaultDispatcher-worker-1
D
Before withContext: main
Inside withContext: DefaultDispatcher-worker-1
After withContext: DefaultDispatcher-worker-1
Attempts:
2 left
💡 Hint

Think about how runBlocking and withContext interact with dispatchers.

🔧 Debug
advanced
2:00remaining
Identify the error in this withContext usage

What error will this Kotlin code produce when run?

Kotlin
import kotlinx.coroutines.*

fun main() {
    withContext(Dispatchers.IO) {
        println("Running in IO dispatcher")
    }
}
AUnresolved reference: withContext
BIllegalStateException: This job has not been started
CSuspend function 'withContext' should be called only from a coroutine or another suspend function
DNo error, prints 'Running in IO dispatcher'
Attempts:
2 left
💡 Hint

Check if withContext is called inside a coroutine or suspend function.

❓ Predict Output
advanced
2:00remaining
What is the output of nested withContext calls with different dispatchers?

Analyze the output of this Kotlin coroutine code with nested withContext calls:

Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Start: ${Thread.currentThread().name}")
    withContext(Dispatchers.Default) {
        println("Default: ${Thread.currentThread().name}")
        withContext(Dispatchers.IO) {
            println("IO: ${Thread.currentThread().name}")
        }
        println("Back to Default: ${Thread.currentThread().name}")
    }
    println("End: ${Thread.currentThread().name}")
}
A
Start: main
Default: DefaultDispatcher-worker-1
IO: IO-thread
Back to Default: DefaultDispatcher-worker-1
End: main
B
Start: main
Default: DefaultDispatcher-worker-1
IO: DefaultDispatcher-worker-1
Back to Default: DefaultDispatcher-worker-1
End: main
C
Start: main
Default: main
IO: DefaultDispatcher-worker-1
Back to Default: main
End: main
D
Start: main
Default: DefaultDispatcher-worker-1
IO: DefaultDispatcher-worker-2
Back to Default: DefaultDispatcher-worker-1
End: main
Attempts:
2 left
💡 Hint

Each withContext switches to the specified dispatcher thread pool.

🧠 Conceptual
expert
3:00remaining
Why use withContext instead of launch for dispatcher switching?

Which statement best explains why withContext is preferred over launch when switching dispatchers for a block of code?

A<code>launch</code> switches the coroutine context and waits for the block to complete, while <code>withContext</code> starts a new coroutine that runs concurrently.
B<code>withContext</code> switches the coroutine context and waits for the block to complete, preserving sequential execution, while <code>launch</code> starts a new coroutine that runs concurrently.
C<code>withContext</code> creates a new thread, but <code>launch</code> reuses the current thread without switching context.
D<code>launch</code> is used only for UI threads, while <code>withContext</code> is for background threads.
Attempts:
2 left
💡 Hint

Think about blocking vs non-blocking behavior and sequential code flow.

Practice

(1/5)
1. What is the main purpose of withContext in Kotlin coroutines?
easy
A. To switch the coroutine execution to a different dispatcher or thread
B. To create a new coroutine scope
C. To cancel a running coroutine
D. To launch a coroutine on the main thread only

Solution

  1. Step 1: Understand what withContext does

    withContext is used to change the dispatcher or thread where a coroutine runs, allowing you to move work to a background thread or back to the main thread.
  2. Step 2: Compare options with this purpose

    Only To switch the coroutine execution to a different dispatcher or thread correctly describes switching execution context. Options A, C, and D describe other coroutine features.
  3. Final Answer:

    To switch the coroutine execution to a different dispatcher or thread -> Option A
  4. Quick Check:

    withContext switches dispatcher = B [OK]
Hint: Remember: withContext changes thread for coroutine code [OK]
Common Mistakes:
  • Confusing withContext with launching new coroutines
  • Thinking it cancels coroutines
  • Assuming it only runs on the main thread
2. Which of the following is the correct syntax to switch to the IO dispatcher using withContext?
easy
A. withContext(Dispatchers.IO()) { /* code */ }
B. withContext(IO.Dispatchers) { /* code */ }
C. withContext(Dispatchers.io) { /* code */ }
D. withContext(Dispatchers.IO) { /* code */ }

Solution

  1. Step 1: Recall the correct dispatcher name

    The dispatcher for IO operations is Dispatchers.IO with uppercase IO.
  2. Step 2: Check syntax correctness

    withContext(Dispatchers.IO) { /* code */ } uses the correct syntax: withContext(Dispatchers.IO) { ... }. Options B and C have wrong casing or order, and A incorrectly uses parentheses after IO.
  3. Final Answer:

    withContext(Dispatchers.IO) { /* code */ } -> Option D
  4. Quick Check:

    Correct dispatcher syntax = D [OK]
Hint: Dispatchers.IO is uppercase and no parentheses needed [OK]
Common Mistakes:
  • Using lowercase 'io' instead of 'IO'
  • Adding parentheses after dispatcher name
  • Swapping Dispatchers and IO order
3. What will be the output of this Kotlin coroutine code snippet?
import kotlinx.coroutines.*
suspend fun main() = coroutineScope {
    println("Start on: ${'$'}{Thread.currentThread().name}")
    withContext(Dispatchers.Default) {
        println("Inside withContext on: ${'$'}{Thread.currentThread().name}")
    }
    println("End on: ${'$'}{Thread.currentThread().name}")
}
medium
A. Start on: main Inside withContext on: main End on: main
B. Start on: DefaultDispatcher-worker-1 Inside withContext on: DefaultDispatcher-worker-1 End on: DefaultDispatcher-worker-1
C. Start on: main Inside withContext on: DefaultDispatcher-worker-1 End on: main
D. Compilation error due to thread access

Solution

  1. Step 1: Identify the starting thread

    The main coroutine starts on the main thread, so the first print shows "main" thread.
  2. Step 2: Understand withContext dispatcher switch

    The withContext(Dispatchers.Default) block runs on a background thread named like "DefaultDispatcher-worker-1".
  3. Step 3: Check thread after withContext

    After the block, execution returns to the main thread, so the last print shows "main" again.
  4. Final Answer:

    Start on: main Inside withContext on: DefaultDispatcher-worker-1 End on: main -> Option C
  5. Quick Check:

    withContext switches thread temporarily = C [OK]
Hint: withContext changes thread only inside its block [OK]
Common Mistakes:
  • Assuming thread stays switched after withContext
  • Thinking withContext runs on main thread always
  • Confusing coroutineScope with launch
4. Identify the error in this Kotlin coroutine code using withContext:
fun fetchData() {
    withContext(Dispatchers.IO) {
        println("Fetching data")
    }
}
medium
A. Incorrect dispatcher name, should be Dispatchers.Main
B. Missing suspend modifier on fetchData function
C. withContext cannot be used inside functions
D. No error, code is correct

Solution

  1. Step 1: Check usage rules of withContext

    withContext is a suspend function and must be called from a suspend function or coroutine.
  2. Step 2: Analyze fetchData function signature

    fetchData is a regular function without suspend, so calling withContext inside it causes a compile error.
  3. Final Answer:

    Missing suspend modifier on fetchData function -> Option B
  4. Quick Check:

    withContext requires suspend function = A [OK]
Hint: withContext only works inside suspend functions or coroutines [OK]
Common Mistakes:
  • Forgetting to mark function as suspend
  • Thinking dispatcher name is wrong
  • Assuming withContext can be called anywhere
5. You want to perform a heavy computation off the main thread and then update the UI on the main thread. Which code snippet correctly uses withContext to achieve this?
hard
A. suspend fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } }
B. suspend fun process() { withContext(Dispatchers.Main) { // heavy computation } withContext(Dispatchers.Default) { // update UI } }
C. fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } }
D. suspend fun process() { withContext(Dispatchers.IO) { // update UI } withContext(Dispatchers.Default) { // heavy computation } }

Solution

  1. Step 1: Identify correct dispatcher for heavy computation

    Heavy computation should run on Dispatchers.Default to avoid blocking the main thread.
  2. Step 2: Identify correct dispatcher for UI update

    UI updates must happen on Dispatchers.Main to safely interact with the UI.
  3. Step 3: Check function signature and order

    The function must be suspend to call withContext. suspend fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } } correctly uses suspend and switches dispatchers in the right order.
  4. Final Answer:

    suspend fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } } -> Option A
  5. Quick Check:

    Heavy work on Default, UI on Main = A [OK]
Hint: Heavy work on Default, UI updates on Main dispatcher [OK]
Common Mistakes:
  • Running heavy work on Main thread
  • Updating UI off the Main thread
  • Not marking function as suspend
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard