Is there any reason not to use `Dispatchers.Main.i...
# coroutines
z
Is there any reason not to use
Dispatchers.Main.immediate
on Android?
a
It works as advertised. If you're asking whether you should or shouldn't use it in a particular situation, use the regular
Dispatchers.Main
instead 🙂
z
I guess I don’t understand why I wouldn’t want immediate execution when possible
m
I guess you could theoretically end up in a situation where some coroutines are never scheduled, because other coroutines are always taking it’s spot.
p
If you're asking whether you should or shouldn't use it in a particular situation, use the regular
Dispatchers.Main
instead
That implies that there are situations where
immediate
is not save. Why do you think so and when? @Adam Powell
o
I think the reasons that
immediate
is not safe have to do with this text:
Immediate dispatcher is safe from stack overflows and in case of nested invocations forms event-loop similar to Dispatchers.Unconfined. The event loop is an advanced topic and its implications can be found in Dispatchers.Unconfined documentation.
Looking in the Unconfined documentation, it seems to affect strict ordering of nested unconfined dispatches, which
immediate
would also be affected by. So, you should avoid nesting it, or just use the non-immediate version instead.
z
So the issue would be that ordering is no longer guaranteed?
o
Yes, in the case of nested
withContext
calls
z
Meaning, with
Main
, everything is posted to the main thread, while
Main.immediate
may execute things immediately when there was work dispatched to the end of the
Main
event loop?
o
not only that, but see the example in the Unconfined docs, just replace
Dispatchers.Unconfined
with the immediate one and the docs imply the same outcome is possible
👍 1
a
Right, the stuff above. Sorry to drop that cryptic statement and run before 🙂
safe places to use it generally include quick hops to the main thread to read or apply a single value in a
withContext
block. I wouldn't recommend it for things like flow collection or anything where you're going to suspend several times there unless you really know what you're doing.
Most people get skittish about the idea of "posting to the main thread" being slow, but generally that's been from prior experience posting to views, view `Handler`s or just `Handler`s that you create yourself
so you don't need to worry about waiting for the next vsync pulse (up to 16ms) for a continuation to resume
which "regular" handlers do by default to keep ordering with pending frames
now places where you should use
Dispatchers.Main.immediate
include some circumstances like when you really don't want the ability for anything else on the main thread to happen before you resume, such as a lifecycle state changing
which can come up in some flow collection situations if you're observing something and you need to react to it now during the current lifecycle state before it changes, e.g. apply a fragment transaction or something else that might alter what you'd include in
savedInstanceState
👍 1
anyway if your primary concern is performance/latency,
Dispatchers.Main
won't be a problem. The way it interacts with the main thread looper is about as efficient of an event loop trampoline as you can get and it preserves expectations that a lot of code is written around. Some folks I know that do a lot of work with RxJava in production compared this style against a
.immediate
-style scheduler they had written and didn't see an appreciable difference, but a lot of weird bugs in their code went away.
👍 1