Sorry to dig up an old thread. I’m trying to understand how cancellations work in the case of blocking code in coroutines.
Ideally, cancellation of a job would interrupt the thread running the blocking code, or at least allow the blocking code to complete but ignore it’s results/exceptions. I tried using @elizarov 's second example from above, switching to a newSingleThreadContext
but doing so causes the job to no longer be cancelable. Calling job.cancel()
returns true
but the coroutine keeps executing.
In trying to debug this, I tried using run
along with suspendCancellableCoroutine
but the outcome was the same.
Submitting the block to an executor has the behavior I expect:
suspend fun <T> runInExecutor(executor: Executor, block: () -> T): T = suspendCancellableCoroutine { cont ->
executor.execute {
try {
cont.resume(block())
} catch (e: Throwable) {
if (!cont.isCompleted) cont.resumeWithException(e)
}
}
}
However, I can’t seem to figure out why the run()
solution doesn’t work. Is run()
thinking CommonPool
and newSingleThreadContext
are the same and not actually suspending?
Here’s a rather contrived example demonstrating what I’m talking about: Blocking coroutine behavior · GitHub