Start and Suspend a Coroutine in Kotlin

· 2 min read
Start and Suspend a Coroutine in Kotlin
Kotlin Coroutines Table Content

1, Introduction to Coroutine in Kotlin
2, Non-blocking in Kotlin Coroutines
3, Start and Suspend a Coroutine in Kotlin (This article)

With the previous articles (Introduction to Coroutine in Kotlin) on Kotlin Coroutine, we know there are two main ways to start a coroutine: launch and async

// launch
val job = GlobalScope.launch {
  // Perform a long-running task in the background
  delay(1000L)
  println("Hello, world!")
}
runBlocking {
  job.join()
}


// async
val result = GlobalScope.async {
  return@async URL("https://catfact.ninja/fact").readText()
}
runBlocking {
  val data = result.await()
  println(data)
}

When we have a closer look at the delay method:

public suspend fun delay(timeMillis: Long) {
    if (timeMillis <= 0) return // don't delay
    return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
        cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
    }
}

We notice that we have a suspend keyword here. The "suspend" keyword is used to indicate (keep this in mind) that a function can be paused and resumed at a later time. A suspend function can be called only from another suspend function or from a coroutine.

Suspend functions are used in conjunction with the coroutine builders such as launch, async, and runBlocking. They allow the program to pause the execution of a coroutine and yield control back to the coroutine dispatcher. This allows other coroutines to run and perform computation while the suspended function is waiting for a result.

For example, if you have a function that retrieves data from a network, you can use the suspend keyword to indicate that the function can be paused while waiting for the network response.

fun main() {

    val run = GlobalScope.async {
        val content = retrieveContent()
        println("fetched: $content")
    }
    
    
	// we are using runBlocking here to make sure the async Coroutine can be finished.
    runBlocking {
        run.await()
    }
}

suspend fun retrieveContent(): String = withContext(Dispatchers.IO) {
    URL("https://catfact.ninja/fact").readText()
}

// output will be:
fetched: {"fact":"Purring does not always indicate that a cat is happy and healthy - some cats will purr loudly when they are terrified or in pain.","length":129}

In this example, the function retrieveContent is marked as suspend function, this function can be called only from other suspend function or from a coroutine. Notice that we are actually calling the withContext inside our new method retrieveContent. withContext  is a Kotlin method which provide the awesome feature that it will switch into a new thread and return back to previous thread automatically. Suspend keyword won't actually suspend the coroutine, it will call the Kotlin method who will really own the coroutine suspend code.

Suspend functions are a powerful feature of coroutines that allow you to write asynchronous code that is easy to read and understand. They allow you to write code that looks like it is executing synchronously, while still allowing the program to perform other tasks in the background.

Summary

We now know the keyword suspend indicates a function can be paused and resumed at a later time, not really suspend the coroutine in Kotlin.