Last active
February 4, 2021 22:52
-
-
Save Munzey/212f38879039987a4c819c53d1d393cd to your computer and use it in GitHub Desktop.
launch inside async cancellation weirdness
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.coroutines.* | |
import kotlin.coroutines.coroutineContext | |
// doesn't work as I expected :/ | |
// this may just be bad practice to hide the launching of a new coroutine, but curious why it doesnt work the same as in the other example file | |
suspend fun coroutineScopeWrapper(block: suspend (parentScope: CoroutineScope) -> Unit) { | |
coroutineScope { | |
val job = async { | |
block(this) | |
} | |
try { | |
job.await() | |
} catch (ex: CancellationException) { | |
println("cancelled") //doesnt seem to reach here | |
} | |
} | |
} | |
fun main() { | |
runBlocking { | |
coroutineScopeWrapper { parentScope -> | |
launch { | |
delay(100) | |
println("reaches here") | |
parentScope.cancel() | |
} | |
launch { | |
delay(1000) | |
println("should never reach here but does") //prints, but would have thought cancelling scope would stop this | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.coroutines.* | |
import kotlin.coroutines.coroutineContext | |
// works as I expected | |
fun main() { | |
runBlocking { | |
val job = async { | |
val parentScope = this | |
launch { | |
delay(100) | |
println("reaches here") | |
parentScope.cancel() | |
} | |
launch { | |
delay(1000) | |
println("never reaches here") // cancelling parent scope so expect this to never print | |
} | |
} | |
try { | |
job.await() | |
} catch (ex: CancellationException) { | |
println("reaches here") // job.await rethrows cancellation exception | |
} | |
} | |
} |
Ah, looks like cancelling a launch
-ed coroutine doesn't affect other coroutines 🤔
To cancel everything you'd use this:
import kotlinx.coroutines.*
// doesn't work as I expected :/
// this may just be bad practice to hide the launching of a new coroutine, but curious why it doesnt work the same as in the other example file
suspend fun coroutineScopeWrapper(block: suspend CoroutineScope.() -> Unit) {
coroutineScope {
val job = async {
block()
}
try {
job.await()
} catch (ex: CancellationException) {
println("cancelled") //doesnt seem to reach here
}
}
}
fun main() {
runBlocking {
coroutineScopeWrapper {
launch {
delay(10)
this@coroutineScopeWrapper.cancel()
}
launch {
delay(1000)
println("should never reach here but does") //prints, but would have thought cancelling scope would stop this
}
}
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To properly pass
async
'sCoroutineScope
down to thelaunch
invocations:Still doesn't explain why
cancel()
doesn't cancel the other launched coroutine though.