Is there a shorter/better way to properly cancel t...
# coroutines
l
Is there a shorter/better way to properly cancel the current suspending function?
Copy code
suspend fun cancelNow(): Nothing = suspendCancellableCoroutine<Nothing> { c -> c.cancel() }
e
throw CancellationException()
l
There's no behavior difference regarding structured concurrency between the two approaches?
e
Minor difference. When you throw an exception the coroutine is not cancelled until the exception propagates to the top level of coroutine. Some code might catch it, for example. I cannot think of a sensible use-case where it makes a difference, though.
l
Since I'm planning to make a public API, I want to implement structured concurrency in the best possible way. In my case, tied to Android's lifecycle, catching the
CancellationException
would be a programmer error, so I think it's always safer to prevent it from working. What do you think about that? Also, cancellation of the scope would start sooner in case of
finally
block, right? If so, I'm wondering why there's no such a
cancelNow()
.
e
I would still rely on exceptions. They are more explicit.
So, for example,
withContext { ... }
. When something breaks inside it rethrows exception outside, but does not cancel parent coroutine.
Whenever possible, we use exceptions. They are more familiar to developers
l
I see, but that makes the behavior inconsistent with the rest of the code in that function I'm writing where I'm using
CompletableDeferred.cancel()
. One may think: Let's catch this
CancellationException
, have it working in the case I do
throw CancellationException()
, but not working in the case of cancellation by the
CompletableDeferred
. I'd not do this mistake, but I'm afraid that someone could do it. That's why I'm thinking something like
suspend fun cancelNow(): Nothing
could come handy to make the behavior consistent when there's multiple cancellation cases.
e
Maybe.