I was expecting this to hang my UI ```viewModelSc...
# coroutines
c
I was expecting this to hang my UI
Copy code
viewModelScope.launch {
  while (true) {
    delay(5_000)
    state.counter++
  }
}
it did not hang. so I took a look into
delay
and it doesn't specify withContext or anything. Where does that delay actually happen? Am I missing something basic here?
j
There's a delay interface a dispatcher implements
Failing that, it's scheduled on Default
You should pretty quickly reach that logic if you stepped into it
j
Why do you expect this to freeze the UI? The delay only delays this coroutine, not others. It's a suspending operation, so it doesn't block the UI thread, thus other coroutines can run on this thread during the wait time.
💯 1
☝️ 2
c
I guess i was expecting it to freeze the ui because i was expecting to drill into the method and see withContext.
i also expected the docs to maybe mention what dispatcher the delay happens on.
but i guess i should just take it for granted that if i come across a suspend function (esp in the standard library) that it should be main safe
t
Never assume that, always check 🙂 It's easy to miss that a suspend function does a network call on another injected dispatcher, but then does an heavy computation on the result that occurs in the call dispatcher.
x
Even a
delay
executed on the main thread, wouldn't freeze the UI. This is because
delay
is suspend function and, when suspend functions get effectively suspended, what's really happening is that the function finishes returning
COROUTINE_SUSPENDED
and immediately releasing the thread while waiting to resume (you can see this if you take a look into the equivalent Java code). If you want to block the UI, you should use blocking code. The following code (only working on JVM targets) will freeze the UI:
Copy code
viewModelScope.launch {
  while (true) {
    Thread.sleep(5_000)
    state.counter++
  }
}
☝️ 1
👍 1
t
suspending does not implies context switch or yielding, it's up to the implementation. if you have a
Copy code
suspend fun doHeavyWork() { var i = 0; while(true) { i++ } }
And call that from maindispatcher it will block UI.
Add a yield() in the loop or wrap in a withContext() or other ways to switch dispatcher then it won't block UI anymore.