Why do kotlin coroutines block this code?

Why will this code never print Hello World?

runBlocking(Dispatchers.Main) {
    launch {
        delay(1)
        println("Hello world")
    }
}

But this will print

runBlocking {
    launch {
        delay(1)
        println("Hello world")
    }
}

Upvotes: 3

Views: 546

Answers (1)

Pawel
Pawel

Reputation: 17288

From what I see first example outright freezes the app (when used inside a button click listener).

The issue is you're causing a deadlock:

  1. Dispatchers.Main works by posting (dispatching) coroutines to main application looper
  2. runBlocking blocks the main application thread
  3. main looper will never get to run posted coroutine because it's waiting for runBlocking to finish

You can slightly alleviate the "issue" by using Dispatchers.Main.immediate instead which is a little smarter version of base dispatcher - it doesn't post coroutine to main looper if it's already running on the main thread and executes it in-place.

This will allow you to run the launch block, however delay will once again post coroutine to continue on main looper and cause another dead lock.

Second code sample has no issues since coroutines running there do not interact with main thread (aside from runBlocking it).

Upvotes: 4

Related Questions