Hi, everyone! i have a question. Does using `withC...
# coroutines
d
Hi, everyone! i have a question. Does using
withContext(Dispatchers.Main)
produce the same effect as specifying
Dispatchers.Main
as a parameter to
launch
? I think it may be same effect. but i'm not sure..
Copy code
private var supervisorJob = SupervisorJob()
private var scope = CoroutineScope(supervisorJob + Dispatchers.Default)
// 1
 scope.launch {
   withContext(Dispatchers.Main) {
     // some code
   }
 }

// 2
scope.launch(Dispatchers.Main) {
     // some code
}
j
2 is faster because 1 will dispatch to the default dispatcher before then dispatching to main. I believe 1 should also dispatch back to default once the main block completes (only to then end).
d
Thank you! One more question, it means when we use coroutine builder such as
launch
,
async
etc.., new coroutine is created. but does it need to dispatch the same dispatcher(in this case Dispatchers.Default) even though the initial scope(parent scope) uses Dispatchers.Default? Until now, I always thought that child coroutines would automatically follow the parent's dispatcher, so I didn't know that they would be dispatched again when created.
j
Yes it is similar to how a
Runnable
which is already executing on an
Executor
can enqueue additional `Runnable`s on the same executor but those must wait until the current one is finished (or until another thread picks them up). If you explicitly want a new coroutine to be entered synchronously (i.e., without dispatch) you can pass
start = CoroutineStart.UNDISPATCHED
. This can be useful if you want to ensure that the new child coroutine reaches its first suspension point before doing something else.
e
also
Dispatchers.Main.immediate
will start undispatched if
Main
is the current dispatcher
j
Yep, and
Unconfined
. I wasn't trying to be exhaustive, but there are indeed only a couple ways it can happen.
d
I really appreciated your explanation! Quick recap, 1. All coroutines are dispatched once when they are created (if CoroutineStart.UNDISPATCHED is not used). 2. All coroutines are not executed immediately; instead, they are enqueued according to the scheduler policy of the dispatcher. Therefore, they may not be executed immediately at the moment they are invoked. However, if CoroutineStart.UNDISPATCHED is used, the coroutine is executed immediately on the current dispatcher (or thread) until the first suspension point is reached (execution is guaranteed). In other words, when using the default launch, the coroutine block is not executed immediately upon reaching it, but is enqueued by the dispatcher to be processed alongside other tasks(coroutines). If i misunderstood, please tell me what part is wrong :)
e
by default, it is up to the dispatcher to decide whether the new coroutine should be dispatched or not
as mentioned earlier, Main.immediate may not dispatch if it is already running, and Unconfined is always undispatched
there is also
CoroutineStart.LAZY
which doesn't start the coroutine at all and
ATOMIC
which forces dispatch, but you should generally not use either
d
Thank you. It depends on the dispatcher. and i read the document. Then, when the dispatcher decides that dispatching is necessary, I believe that the default launch without any parameters is not executed immediately. it resumes at some point(asynchronously). Is that correct?
👌 1