natario1
12/10/2023, 11:25 AMIn order to execute a block in place, it is required to return false fromI know that if I return false fromand delegate theisDispatchNeeded
implementation todispatch
in such cases.Dispatchers.Unconfined.dispatch
isDispatchNeeded
, dispatch
should not even be called (except maybe for yield?). So in which case should one delegate to Dispatchers.Unconfined.dispatch()
? This suggestion is mentioned in the docs as something important but I haven’t seen it done in any open source implementation.Sam
12/11/2023, 10:32 AMyield()
is the reason for this rule. From the docs for `yield()`:
If the coroutine dispatcher isWe're dealing with a performance optimisation on top of a performance optimisation here. 1. If you're already on the correct thread, you can return false from, this functions suspends only when there are other unconfined coroutines working and forming an event-loop. For other dispatchers, this function callsUnconfined
and always suspends to be resumed later regardless of the result ofdispatch
. If there is noisDispatchNeeded
in the context, it does not suspend.CoroutineDispatcher
isDispatchNeeded()
to indicate that the continuation can run in-place to avoid the cost of a dispatch.
2. But, if the continuation is a result of a call to yield()
, the continuation should not run in-place, because the user explicitly indicated that other coroutines should get a chance to run first. This is why dispatch
is always called for a yield()
, even when isDispatchNeeded()
is false
.
3. But, if there are no other queued coroutines, yield()
may still perform an immediate dispatch. This is the reason that Dispatchers.Unconfined
has a funky implementation of dispatch
that effectively tells the continuation "no, really, do the immediate dispatch anyway". You cannot do this from your own dispatcher implementations, because you're forbidden from performing an immediate dispatch from the dispatch
method.
The final optimisation (3) is the only thing you gain by delegating to Dispatchers.Unconfined
. It allows you to perform an immediate dispatch during a yield()
if you identify that there are no other coroutines that you can schedule instead.Sam
12/11/2023, 10:33 AMyield()
, because it will always dispatch even when there's nothing to yield to.natario1
12/11/2023, 2:49 PMSam
12/11/2023, 2:53 PM