DispatchedTask

But there is still one gap. We know that CoroutineDispatcher defines dispatch() to take a CoroutineContext and a Runnable. Here is its signature:

public abstract fun dispatch(context: CoroutineContext, block: Runnable)

So how is it that DispatchedContinuation sends itself as the Runnable, as we just saw? Here is the snippet again:

dispatcher.dispatch(context, this)

As mentioned before, DispatchedContinuation also implements the DispatchedTask interface. This interface extends Runnable by adding a default implementation of run() that can trigger resume() and resumeWithException() in the continuation, as shown here:

public override fun run() {
try {
val delegate = delegate as DispatchedContinuation<T>
val continuation = delegate.continuation
val context = continuation.context
val job = if (resumeMode.isCancellableMode) context[Job] else null
val state = takeState()
withCoroutineContext(context) {
if (job != null && !job.isActive) {
continuation.resumeWithException(
job.getCancellationException())

} else {
val exception = getExceptionalResult(state)
if (exception != null) {
continuation.resumeWithException(exception)
} else {
continuation.resume(getSuccessfulResult(state))
}

}
}
} catch (e: Throwable) {
throw DispatchException("Unexpected exception running $this", e)
}
}
Notice that withCoroutineContext() is called before calling resume(); this guarantees that all elements that are part of the CoroutineContext are set before its execution.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.162.49