user3769778
user3769778

Reputation: 967

How to create this coroutines in kotlin?

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

Answers (1)

Marko Topolnik
Marko Topolnik

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

Related Questions