Hi I am new to coroutines. 1. Does coroutines need...
# coroutines
g
Hi I am new to coroutines. 1. Does coroutines needs to be inside runblocking{} always 2. If not, then how do I run the following code without blocking the main thread
Copy code
fun main(args: Array<String>) {
        download()
    print("from main")
}
 fun download(){
     runBlocking {
         coroutineScope {
             launch {
                 delay(10000)
                 println("from coroutine")
             }
         }
     }
}
3. I want the "from main" to be executed first. How can I do that? . Should I call download() from a new thread?
j
Coroutines need a scope to run.
runBlocking
is one way to give it a scope (it blocks the thread that calls it until all child coroutines are done). This is why it's the usual way to start coroutines from a
main
function. One way to do what you want is the following:
Copy code
fun main(args: Array<String>) {
    // runBlocking ensures we don't finish the process execution before the end of the coroutines
    runBlocking {
        // launch is to start a separate coroutine to run the download() suspend function
        // it will start the given block asynchronously, so we immediately go to "from main"
        launch {
            download()
        }
        print("from main")
    }
}

suspend fun download() {
    delay(10000)
    println("from coroutine")
}
Also if
download()
contains some blocking calls, it would be advisable to wrap these blocking calls into
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
so they run on a separate thread pool to avoid blocking the main thread
g
So runblocking{} blocks the current thread and also it provides a scope. Code inside the launch{} executes in the background. Like starting a new thread. If any code needs to be executed after starting a coroutine it should be inside the runblocking{}. Is my understanding correct?
j
runblocking{} blocks the current thread and also it provides a scope
Correct.
Code inside the launch{} executes in the background
Yes, it's started asynchronously so the code that follows the
launch
will run concurrently with the code that's inside the
launch
. Both pieces of code could be executed on the same thread or different threads depending on the coroutine context (and especially the dispatcher in the context). In this specific example, everything will run on the main thread.
If any code needs to be executed after starting a coroutine it should be inside the runblocking{}
You can also put code after
runBlocking
(if it's non-suspending) but at that point the launched coroutines will be guaranteed to be complete, so it won't run concurrently with those coroutines
g
Okay I understand now.Thank you @Joffrey
j
Code inside the launch{} executes in the background. Like starting a new thread.
No, not like starting a new thread. Starting a new thread allows parallelism. Whereas, the way
launch
is used in your example (i.e without switching dispatcher), all that
launch
exhibits is concurrency.
👍 1