Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to suspend coroutine until Task<T> is complete

Tags:

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

like image 314
Dima Rostopira Avatar asked May 13 '18 11:05

Dima Rostopira


People also ask

How do you wait for coroutine to finish Kotlin?

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.

Can coroutines be suspended and resumed?

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.

What is coroutine suspend?

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.

How to suspend a coroutine in Android?

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.

What is the use of suspend function in Kotlin?

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 ...

What is final_suspend in a coroutine?

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.

How to execute a block in suspendcancellablecoroutine?

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.


1 Answers

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.

like image 179
Roman Elizarov Avatar answered Oct 10 '22 17:10

Roman Elizarov