StragaSevera
01/31/2021, 1:42 PMstart()
method, but does not happen if I remove the class and copy contents of the start()
method to the main()
function. It seems like there is some caching issue...Ian Lake
01/31/2021, 4:09 PMZach Klippenstein (he/him) [MOD]
01/31/2021, 4:33 PMcountTo
coroutines are running as children of your scope
property, not as children of the coroutine running calculate
. So when you cancel the coroutine that the calculate
function is running in, it doesn’t do anything. To fix this, and in general, whenever you have a suspend
function, any coroutines you launch should usually be children of the current scope, not of an external one. You can get the current scope in a suspend function using the coroutineScope
function. Your calculate
function should look like this:
private suspend fun calculate(): Int {
// Wrap with coroutineScope.
return coroutineScope {
// Now, inside this lambda, this is the CoroutineScope of the current
// coroutine, so you can call async without an explicit receiver and it
// will launch a child of the current scope.
val a = async { countTo(10) }
val b = async { countTo(20) }
// Need a qualified return now since this is in a lambda, but
// you could also just omit the return keyword entirely.
return@coroutineScope a.await() + b.await()
}
}
This also takes advantage of one of the other features of structured concurrency – the coroutineScope
function won’t return until all the coroutines launched inside it have completed, which means it’s much harder to accidentally forget to join a coroutine and leak it.Zach Klippenstein (he/him) [MOD]
01/31/2021, 4:34 PMsuspend fun calculate(): Int = coroutineScope {
val a = async { countTo(10) }
val b = async { countTo(20) }
a.await() + b.await()
}
StragaSevera
01/31/2021, 5:32 PMasync
should be wrapped in coroutineScope
?Youssef Shoaib [MOD]
01/31/2021, 5:40 PMso any call of a suspend function starts a new coroutineNo, it's specifically that any call that starts a coroutine (i.e. any call that's defined as an extension on coroutineScope) should be wrapped in a coroutineScope block if inside a normal suspend function. If you call any other suspend function then you don't need that coroutineScope block, it's only needed here because
async
is a call that starts a coroutineStragaSevera
01/31/2021, 5:42 PMZach Klippenstein (he/him) [MOD]
01/31/2021, 6:42 PMCoroutineScope
– not both.StragaSevera
01/31/2021, 6:42 PMZach Klippenstein (he/him) [MOD]
01/31/2021, 6:48 PMStragaSevera
01/31/2021, 6:49 PM