suspend fun CoroutineScope.SMR() {
launch { ... }
}
From the look of things withContext should just grab the old context, merge with new context and dispatch if the dispatcher changed.
b
bezrukov
10/14/2022, 7:07 AM
Is
dispatcher
here a single-threaded dispatcher? Is it the same dispatcher/thread where runBlocking was called?
bezrukov
10/14/2022, 7:07 AM
e.g. Dispatchers.Main
t
Trevor Stone
10/14/2022, 3:14 PM
This is expected behavior due to structured concurrency. The first example of withContext, the inner
this
is a new child coroutine scoped to the parent caller. The inner coroutine will not complete and return until all of its children are completed. Essentially if you stop the work inside of launch after some time, it will function closer to your expectation.
In the second example no new coroutineScope is created, thus the launch is bound to the caller's coroutine scope
e
Exerosis
10/16/2022, 2:31 PM
@Trevor Stone what would the correct way to go about this be?
t
Trevor Stone
10/16/2022, 2:32 PM
What are you trying to do?
j
Joffrey
10/17/2022, 9:38 AM
@Exerosis
withContext
is not only switching the context here, it also creates a nested scope (like
coroutineScope { ... }
) and waits for all children to finish.
If you just want to launch with added context, just pass the extra context directly to launch:
Copy code
fun CoroutineScope.SMR() {
launch(dispatcher) { ... }
}
Also, avoid making a
suspend
function with
CoroutineScope
receiver. It's confusing because
suspend
functions are usually expected to finish their work before returning, while
CoroutineScope
extensions are expected to return almost immediately and launch child coroutines
e
Exerosis
10/17/2022, 9:07 PM
@Joffrey Ah I see, I feel like I keep making this same mistake. I don't really understand the advantages of it working in this way. However I think in my case I want a CoroutineScope extension and you are right I don't need to mark it as suspend.