Same example with some result (for single thread dispatcher):
suspend fun awaitTrigger(): T {
var t: T? = null
coroutineScope {
val scope = this
launch { t = awaitAutomaticTrigger(); scope.cancel() }
launch { t = awaitManualTrigger(); scope.cancel() }
}
return t!!
}
Why not just cancel the scope when a child wins? A basic approach:
suspend fun awaitTrigger() { coroutineScope {
val scope = this
launch { awaitAutomaticTrigger(); scope.cancel() }
launch { awaitManualTrigger(); scope.cancel() }
} }
It should gracefully cancel all losers. Also more flexible: we can for example always wait for some specific slow child by skipping cancel invocation.
Louis CAD A (fixed) basic approach ;-)
suspend fun awaitTrigger1() { coroutineScope { val win = coroutineContext::cancelChildren launch { awaitAutomaticTrigger(); win(null) } launch { awaitManualTrigger(); win(null) } } }version with some result
suspend fun awaitTrigger2(): T = coroutineScope { val deferred = CompletableDeferred<T>() launch { deferred.complete(awaitAutomaticTrigger()) } launch { deferred.complete(awaitManualTrigger()) } deferred.await().also { coroutineContext.cancelChildren() } }pl.kotl.in/i1YWEs2lC pl.kotl.in/oQyBHb2bg