Shawn Witte
10/30/2020, 11:37 PMsuspend
function, I usually wrap the launch
or async
call with withContext
(although, it looks like I should be using coroutineScope
a little more often). This will tie the new coroutines into the structured concurrency of the calling coroutine, which is all fine and dandy.
On the other hand, suppose I had something along the lines of
shortLivedScope.launch {
// some stuff
longLivedScope.launch { performSomeTasks() }
// some stuff
}
What is the relationship between the coroutines I have now launched?Adam Powell
10/31/2020, 12:56 AMstreetsofboston
10/31/2020, 3:09 AMShawn Witte
10/31/2020, 8:10 PMlongLivedScope
) is canceled, then the outer coroutine wouldn't be canceled in my example unless I add a join
call, correct?
2. In my example, will the outer coroutine finish if the inner one is still running? So if I call join
on the outer coroutine, and it reaches the end, but the inner coroutine is still running, will the join
call suspend? My instinct is that it will not suspend, but if the inner coroutine was started without an explicit scope (just an unadorned launch
), then the outer join
would suspend.
All of this assumes the scopes are otherwise unrelated (which is a good consideration that I was taking for granted)Adam Powell
10/31/2020, 10:38 PMCoroutineScope
. It just so happens that launch
, async
and coroutineScope
all have a CoroutineScope
receiver to their lambda blocks, so you can call it with an implicit this
in those places.join
never causes cancellation and does not affect the propagation behavior of cancellation.Shawn Witte
10/31/2020, 11:10 PMasync/wait
propagates a cancellation (as in the linked article) because there's no value received, just a thrown CancellationException
that propagates up the chain. So launch/join
and async/await
handle cancellations differently (which makes sense because they handle exceptions differently, and cancellation is implemented with an exception).Adam Powell
10/31/2020, 11:23 PMthrow CancellationException()
yourself.try {
someDisjointDeferred.await()
} catch (ce: CancellationException) {
delay(timeout)
tryAgain()
}
will work, or if the delay
in the catch will throw another CancellationException
because the calling job is cancelledShawn Witte
10/31/2020, 11:29 PM