Is withTimeout() a coroutine builder? Does it block the calling thread?

395 Views Asked by At
  1. There are three main coroutine builders launch, async, runBlocking. My question is about withTimeout() is it a coroutine builder?. if it is, what does it return? what is its scope? what is its dispatcher?

  2. I have following piece of code:

    val myScope =  CoroutineScope(Dispatchers.Default)
    
    runBlocking{
    
       myScope.launch {  //coroutine#1
         Log.i(TAG, "First coroutine launched")
       }
    
       withTimeout(3000){
         delay(2000)
         Log.i(TAG, "withTimeout block executed")
       }
    
       myScope.launch { //coroutine#2
          Log.i(TAG, "Second coroutine launched")
       }
    
    }
    

The output is:

First coroutine launched
withTimeout block executed
Second coroutine launched

Here you can see withTimeout takes two seconds to complete the task but still coroutine#2 executed after this block. It means that withTimeout blocks the calling thread. If it does not block the calling thread then output should be like this:

First coroutine launched
Second coroutine launched
withTimeout block executed

Am I right? please help me in understanding this scenario. Thank you

1

There are 1 best solutions below

3
On

withTimeout() is a suspend function so it should be invoked from a coroutine or another suspend function.

Coroutine builder is a bridge from the normal to the suspending world.

There are three main coroutine builders launch, async, runBlocking. My question is about withTimeout() is it a coroutine builder?. if it is, what does it return? what is its scope? what is its dispatcher?

According to the docs: "Runs a given suspending block of code inside a coroutine ...", I've used logs to check, and it appears that it uses the current coroutine to execute the block of code, but it also waits for it to finish. withTimeout() is not a coroutine builder, because it is a suspend function by itself and it's not a bridge from the normal to the suspending world.
It returns whatever the block, passed as the last parameter, returns. It creates another scope (TimeoutCoroutine) and uses it as a receiver. It uses the current context's CoroutineDispatcher.

It means that withTimeout blocks the calling thread

withTimeout() is a suspend function, it doesn't block the thread, but suspends the coroutine it is launched in until the block is finished execution, or timeout fires. If block executes longer than provided timeout, then an exception will be thrown and coroutine#2 will not be executed.