Unconfined

expect val Unconfined: CoroutineDispatcher

A coroutine dispatcher that is not confined to any specific thread. It executes the initial continuation of a coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid stack overflows.

Event loop

Event loop semantics is a purely internal concept and has no guarantees on the order of execution except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost unconfined coroutine.

For example, the following code:

withContext(Dispatchers.Unconfined) {
println(1)
withContext(Dispatchers.Unconfined) { // Nested unconfined
println(2)
}
println(3)
}
println("Done")

Can print both "1 2 3" and "1 3 2". This is an implementation detail that can be changed. However, it is guaranteed that "Done" will be printed only when both withContext calls are completed.

If you need your coroutine to be confined to a particular thread or a thread-pool after resumption, but still want to execute it in the current call-frame until its first suspension, you can use an optional CoroutineStart parameter in coroutine builders like launch and async setting it to the value of CoroutineStart.UNDISPATCHED.

actual val Unconfined: CoroutineDispatcher
actual val Unconfined: CoroutineDispatcher

A coroutine dispatcher that is not confined to any specific thread. It executes initial continuation of the coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid stack overflows.

Event loop

Event loop semantics is a purely internal concept and have no guarantees on the order of execution except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost unconfined coroutine.

For example, the following code:

withContext(Dispatchers.Unconfined) {
println(1)
withContext(Dispatchers.Unconfined) { // Nested unconfined
println(2)
}
println(3)
}
println("Done")

Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed. But it is guaranteed that "Done" will be printed only when both withContext are completed.

Note that if you need your coroutine to be confined to a particular thread or a thread-pool after resumption, but still want to execute it in the current call-frame until its first suspension, then you can use an optional CoroutineStart parameter in coroutine builders like launch and async setting it to the value of CoroutineStart.UNDISPATCHED.

actual val Unconfined: CoroutineDispatcher

Sources

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard