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 theisDispatchNeededimplementation todispatchin 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 callsUnconfinedand always suspends to be resumed later regardless of the result ofdispatch. If there is noisDispatchNeededin 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