public class CoroutineDispatcher
Base class that shall be extended by all coroutine dispatcher implementations.
The following standard implementations are provided by kotlinx.coroutines
as properties on
class Dispatchers
objects:
Dispatchers.getDefault
-- is used by all standard builder if no dispatcher nor any other ContinuationInterceptor
is specified in their context. It uses a common pool of shared background threads.
This is an appropriate choice for compute-intensive coroutines that consume CPU resources.
Dispatchers.getIO
-- uses a shared pool of on-demand created threads and is designed for offloading of IO-intensive blocking
operations (like file I/O and blocking socket I/O).
Dispatchers.getUnconfined
-- starts coroutine execution in the current call-frame until the first suspension.
On first suspension the coroutine builder function returns.
The coroutine resumes in whatever thread that is used by the
corresponding suspending function, without confining it to any specific thread or pool.
Unconfined dispatcher should not be normally used in code.
Private thread pools can be created with ThreadPoolDispatcherKt.newSingleThreadContext
and ThreadPoolDispatcherKt.newFixedThreadPoolContext
.
An arbitrary Executor can be converted to dispatcher with ExecutorsKt.from
extension function.
This class ensures that debugging facilities in newCoroutineContext function work properly.
Constructor and Description |
---|
CoroutineDispatcher()
Base class that shall be extended by all coroutine dispatcher implementations.
|
Modifier and Type | Method and Description |
---|---|
void |
dispatch(NonExistentClass context,
java.lang.Runnable block)
Dispatches execution of a runnable block onto another thread in the given context.
|
<T> NonExistentClass |
interceptContinuation(NonExistentClass continuation)
Returns continuation that wraps the original continuation, thus intercepting all resumptions.
|
boolean |
isDispatchNeeded(NonExistentClass context)
Returns
true if execution shall be dispatched onto another thread.
The default behaviour for most dispatchers is to return true . |
public CoroutineDispatcher()
Base class that shall be extended by all coroutine dispatcher implementations.
The following standard implementations are provided by kotlinx.coroutines
as properties on
class Dispatchers
objects:
Dispatchers.getDefault
-- is used by all standard builder if no dispatcher nor any other ContinuationInterceptor
is specified in their context. It uses a common pool of shared background threads.
This is an appropriate choice for compute-intensive coroutines that consume CPU resources.
Dispatchers.getIO
-- uses a shared pool of on-demand created threads and is designed for offloading of IO-intensive blocking
operations (like file I/O and blocking socket I/O).
Dispatchers.getUnconfined
-- starts coroutine execution in the current call-frame until the first suspension.
On first suspension the coroutine builder function returns.
The coroutine resumes in whatever thread that is used by the
corresponding suspending function, without confining it to any specific thread or pool.
Unconfined dispatcher should not be normally used in code.
Private thread pools can be created with ThreadPoolDispatcherKt.newSingleThreadContext
and ThreadPoolDispatcherKt.newFixedThreadPoolContext
.
An arbitrary Executor can be converted to dispatcher with ExecutorsKt.from
extension function.
This class ensures that debugging facilities in newCoroutineContext function work properly.
public boolean isDispatchNeeded(NonExistentClass context)
Returns true
if execution shall be dispatched onto another thread.
The default behaviour for most dispatchers is to return true
.
UI dispatchers should not override isDispatchNeeded
, but leave a default implementation that
returns true
. To understand the rationale beyond this recommendation, consider the following code:
fun asyncUpdateUI() = async(MainThread) {
// do something here that updates something in UI
}
When you invoke asyncUpdateUI
in some background thread, it immediately continues to the next
line, while UI update happens asynchronously in the UI thread. However, if you invoke
it in the UI thread itself, it updates UI synchronously if your isDispatchNeeded
is
overridden with a thread check. Checking if we are already in the UI thread seems more
efficient (and it might indeed save a few CPU cycles), but this subtle and context-sensitive
difference in behavior makes the resulting async code harder to debug.
Basically, the choice here is between "JS-style" asynchronous approach (async actions
are always postponed to be executed later in the even dispatch thread) and "C#-style" approach
(async actions are executed in the invoker thread until the first suspension point).
While, C# approach seems to be more efficient, it ends up with recommendations like
"use yield
if you need to ....". This is error-prone. JS-style approach is more consistent
and does not require programmers to think about whether they need to yield or not.
However, coroutine builders like BuildersKt.launch
and BuildersKt.async
accept an optional enum CoroutineStart
parameter that allows one to optionally choose C#-style CoroutineStart.UNDISPATCHED behaviour
whenever it is needed for efficiency.
Note: This is an experimental api. Execution semantics of coroutines may change in the future when this function returns false
.
BuildersKt.launch
,
BuildersKt.async
,
enum CoroutineStart
public void dispatch(NonExistentClass context, java.lang.Runnable block)
Dispatches execution of a runnable block onto another thread in the given context.
public <T> NonExistentClass interceptContinuation(NonExistentClass continuation)
Returns continuation that wraps the original continuation, thus intercepting all resumptions.