How can I launch a coroutine from a suspend function and have it use the current Scope? (so that the Scope doesn't end until the launched coroutine also ends)
I'd like to write something like the following –
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
go()
}
suspend fun go() {
launch {
println("go!")
}
}
But this has a syntax error: "Unresolved Reference: launch". It seems launch
must be run in one of the following ways –
GlobalScope.launch {
println("Go!")
}
Or
runBlocking {
launch {
println("Go!")
}
}
Or
withContext(Dispatchers.Default) {
launch {
println("Go!")
}
}
Or
coroutineScope {
launch {
println("Go!")
}
}
None of these alternatives does what I need. Either the code "blocks" instead of "spawning", or it spawns but the parent scope won't wait for its completion before the parent scope itself ends.
I need it to "spawn" (launch) in the current parent coroutine scope, and that parent scope should wait for the spawned coroutine to finish before it ends itself.
I expected that a simple launch
inside a suspend fun
would be valid and use its parent scope.
I'm using Kotlin 1.3
and cotlinx-coroutines-core:1.0.1
.
The simplest way to create a coroutine is by calling the launch builder on a specified scope. It Launches a new coroutine without blocking the current thread and returns a reference to the coroutine as a Job. The coroutine is canceled when the resulting job is canceled. The launch doesn't return any result.
The easiest way to create a coroutine scope object is by using the CoroutineScope factory function 1. It creates a scope with provided context (and an additional Job for structured concurrency if no job is already part of the context).
Kotlin coroutines & structured concurrencyIn Kotlin, we can create coroutines using builders such as launch and async , which return a Job instance. This Job may further contain nested coroutine builders that create children Job instances that are computed concurrently.
The launch launches a new coroutine concurrently with the rest of the code, which continues to work independently. The async creates a coroutine and can return the result of the asynchronous task.
How can we use CoroutineScopes in Kotlin? Kotlin’s Coroutines allow the use of suspend functions, Channels and Flows and they all operate in the context of a so-called CoroutineScope. How can we tie it to the lifecycle management of our own components?
Suspend Function In Kotlin. Suspend function is a function that could be started, paused, and resume. One of the most important points to remember about the suspend functions is that they are only allowed to be called from a coroutine or another suspend function. An example is given below, in which we have tried to call the delay() function ...
Coroutines always execute in some context represented by a value of the CoroutineContext type, defined in the Kotlin standard library. The coroutine context is a set of various elements. The main elements are the Job of the coroutine, which we've seen before, and its dispatcher, which is covered in this section.
Suspending functions can be used inside coroutines just like regular functions, but their additional feature is that they can, in turn, use other suspending functions (like delay in this example) to suspend execution of a coroutine. println("World!") You can get the full code here.
You should make the function go
an extension function of CoroutineScope
:
fun main() = runBlocking {
go()
go()
go()
println("End")
}
fun CoroutineScope.go() = launch {
println("go!")
}
Read this article to understand why it is not a good idea to start in a suspend
functions other coroutines without creating a new coroutineScope{}
.
The convention is: In a suspend
functions call other suspend
functions and create a new CoroutineScope
, if you need to start parallel coroutines. The result is, that the coroutine will only return, when all newly started coroutines have finished (structured concurrency).
On the other side, if you need to start new coroutines without knowing the scope, You create an extensions function of CoroutineScope
, which itself it not suspendable
. Now the caller can decide which scope should be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With