Reputation: 967
I am trying to print Hello in between World 4
from this code.
import kotlinx.coroutines.*
import java.util.*
fun main() = runBlocking <Unit> {
launch { //COR-1
var now = Date().time
val c= timeConusmingFunct(now) //may be some IO work
print(" World $c") //once done lets process it
}
launch{ //COR-2
print(" in between")
}
print("Hello ")
}
suspend fun timeConusmingFunct(now: Long): Int{
while(Date().time-now <4000){
//a way to block the thread
}
return 4
}
My understanding is that when main thread execute it will face COR-1 and move onto next COR-2 and then move to final print("Hello")
. As COR-1 will take some time (~4s) and the time consuming funct is marked suspend [which indicates that it will take some time].
The call should have gone to COR-2.
However it prints : Hello World 4 in between
Why this happens, and how do I make my code work as intended Hello in between World 4
with help of coroutine ?
Upvotes: 2
Views: 279
Reputation: 200296
You need this minimal change to your spin-waiting loop:
while (Date().time - now < 4000) {
yield()
}
The concurrency in coroutines is cooperative, suspension happens when the code explicitly asks for it. Normally it happens transparently because you call a suspendable function, but in your case you must add it in since you aren't otherwise calling any suspendable functions.
what if I had some Image processing in that timeConsumingcode to do. It will block the main thread. I want it to be handled by co routine.
Image processing is a CPU-bound task and, since it's not a task that must be pinned to the GUI thread, you are better off handing it over to a thread pool. The most convenient way to do it is to write
withContext(Dispatchers.Default) {
processImage(img)
}
This way your coroutine, that otherwise runs on the main GUI thread, will temporarily jump over to the thread pool to do the long task, and then move back to the GUI thread to go on. While it's running on the thread pool, the GUI thread will be able to serve other GUI events and keep your UI live.
Upvotes: 2