I've recently dove into Kotlin coroutines Since I use a lot of Google's libraries, most of the jobs is done inside Task class
Currently I'm using this extension to suspend coroutine
suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation -> task.addOnCompleteListener { task -> if (task.isSuccessful) { continuation.resume(task.result) } else { continuation.resumeWithException(task.exception!!) } } }
But recently I've seen usage like this
suspend fun <T> awaitTask(task: Task<T>): T = suspendCoroutine { continuation -> try { val result = Tasks.await(task) continuation.resume(result) } catch (e: Exception) { continuation.resumeWithException(e) } }
Is there any difference, and which one is correct?
UPD: second example isn't working, idk why
When we launch a coroutine in Kotlin using launch we are returned the resulting Job . We can wait for the coroutine to finish by calling join() on the Job.
Coroutines provide us an easy way to do synchronous and asynchronous programming. Coroutines allow execution to be suspended and resumed later at some point in the future which is best suited for performing non-blocking operations in the case of multithreading.
A coroutine is an instance of suspendable computation. It is conceptually similar to a thread, in the sense that it takes a block of code to run that works concurrently with the rest of the code. However, a coroutine is not bound to any particular thread.
A suspend function can be used as a regular function, and it will suspend the execution of the coroutine. For example, delay () is a built-in suspending function. Thank Android Studio for the kindly reminder, here we can know that delay () is a suspend function by the arrow icon on the left of the panel.
Suspend Function In Kotlin. Suspend function is a function that could be started, paused, and resume. One of the most important points to remember about the suspend functions is that they are only allowed to be called from a coroutine or another suspend function. An example is given below, in which we have tried to call the delay() function ...
Conversely, there is a final_suspend at the end of the coroutine after the coroutine function body has finished. This gives you a chance to do any extra cleanup, as well as perform some other magic we’ll look at in a future installment.
We can execute a block in suspendCancellableCoroutine with the argument CancellableContinuation. There are three ways to use for CancellableContinuation: Resumes the execution of the corresponding coroutine passing [value] as the return value of the last suspension point.
The block of code passed to suspendCoroutine { ... }
should not block a thread that it is being invoked on, allowing the coroutine to be suspended. This way, the actual thread can be used for other tasks. This is a key feature that allows Kotlin coroutines to scale and to run multiple coroutines even on the single UI thread.
The first example does it correctly, because it invokes task.addOnCompleteListener
(see docs) (which just adds a listener and returns immediately. That is why the first one works properly.
The second example uses Tasks.await(task)
(see docs) which blocks the thread that it is being invoked on and does not return until the task is complete, so it does not allow coroutine to be properly suspended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With