Exerosis
10/14/2022, 3:57 AMrunBlocking {
SMR()
println("test")
}
it hangs when SMR is like:
suspend fun SMR() = withContext(dispatcher) {
launch { ... }
}
But not if it's like:
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.bezrukov
10/14/2022, 7:07 AMdispatcher
here a single-threaded dispatcher? Is it the same dispatcher/thread where runBlocking was called?bezrukov
10/14/2022, 7:07 AMTrevor Stone
10/14/2022, 3:14 PMthis
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 scopeExerosis
10/16/2022, 2:31 PMTrevor Stone
10/16/2022, 2:32 PMJoffrey
10/17/2022, 9:38 AMwithContext
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:
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 coroutinesExerosis
10/17/2022, 9:07 PM