You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
funmain(args:Array<String>) = runBlocking<Unit> {
launch(coroutineContext +CommonPool, start =CoroutineStart.UNDISPATCHED) {
println("I am in ${Thread.currentThread().name}")
withContext(CommonPool) {
println("I am in ${Thread.currentThread().name}")
}
println("I am in ${Thread.currentThread().name}")
}
}
This code prints:
I am in main
I am in main
I am in main
I think it is a bit astonishing. I would have expected:
I am in main
I am in ForkJoinPool.commonPool-worker-1
I am in ForkJoinPool.commonPool-worker-1
The first print has to be in "main" because of the undispatched start. But I would expect withContext to perform the necessary thread switch.
I understand the reason is that even started undispatched, the context is actually already CommonPool and that's why withContext use a fast path, and do not perform thread switch.
However, I think this may cause programming mistakes. Would it be possible somehow, to improve withContext to avoid such mistakes?
The text was updated successfully, but these errors were encountered:
jcornaz
changed the title
CoroutineStart.UNDISPATCHED may make withContext not performing thread switch
CoroutineStart.UNDISPATCHED may cause withContext not performing thread switch
Mar 14, 2018
jcornaz
changed the title
CoroutineStart.UNDISPATCHED may cause withContext not performing thread switch
CoroutineStart.UNDISPATCHED may cause withContext to not perform thread switch
Mar 14, 2018
It is going to be hard to fix, since we don't currently have a mechanism for withContext to figure out that it was running in an UNDISPATCHED coroutine (before its first suspension). Consider slightly modified code:
The first withContext is still running in main, but it does not know about it (it only knows that its parent coroutine has CommonPool as its context), while the second withContext is already in the CommonPool context. Somehow, we need coroutine to know whether it was already dispatched to the appropriate context or not. We don't have this kind of feature at the moment.
So, withContext does not know about UNDISPATCHED. May be it's time to teach it :)
This knowledge will help to solve #3681 as well:
launch(UNDISPATCHED) {
myStateFlow.collectLatest {
// collectLatest can detect that no suspension is needed for the first value
// and execute the collector immediately in the same stack frame
// if the calling coroutine is UNDISPATCHED
}
}
Hello,
please consider the following example:
This code prints:
I think it is a bit astonishing. I would have expected:
The first print has to be in "main" because of the undispatched start. But I would expect
withContext
to perform the necessary thread switch.I understand the reason is that even started undispatched, the context is actually already
CommonPool
and that's whywithContext
use a fast path, and do not perform thread switch.However, I think this may cause programming mistakes. Would it be possible somehow, to improve
withContext
to avoid such mistakes?The text was updated successfully, but these errors were encountered: