我是协程的新手
这是一个流行的例子:
suspend fun findBigPrime(): BigInteger =
withContext(Dispatchers.IO) {
BigInteger.probablePrime(4096, Random()))
}
但是,它可以写成:
suspend fun findBigPrime(): BigInteger =
suspendCancellableCoroutine {
it.resume(BigInteger.probablePrime(4096, Random()))
}
真正的区别是什么?
> 真正的区别是什么?
事实上,几乎没有任何关系。
suspendCancellableCoroutine {
it.resume(BigInteger.probablePrime(4096, Random()))
}
这只会在简单的直接调用之上增加无用的开销
BigInteger.probablePrime(4096, Random())
如果在仍在suspendCancellableCoroutine
块内恢复继续,则协程根本不会挂起。
withContext(Dispatchers.IO) {
BigInteger.probablePrime(4096, Random()))
}
这会挂起协程并在另一个线程上启动内部协程。当内部协程完成时,它会恢复当前协程并显示结果。
在这里使用suspendCancellableCoroutine
是一个"大不"。
withContext
更改块(协程(将在其上运行的上下文,此处将覆盖将协程调度到指定线程的调度程序。虽然suspendCoroutine
/suspendCancellableCoroutine
用于包装异步回调,但异步回调不会阻塞线程,而是在自己的线程上运行。
通常suspendCoroutine
/suspendCancellableCoroutine
的工作是非阻塞的,并且很快就会完成,并且在工作以非阻塞方式完成后恢复继续,也许在其他线程中
。如果你把阻塞代码放在那里,协程的概念就会丢失,它只会阻塞它正在运行的线程。
suspendCoroutine
/suspendCancellableCoroutine
的使用:
// This function immediately creates and starts thread and returns
fun findBigPrimeInNewThread(after: (BigInteger) -> Unit) {
Thread {
BigInteger.probablePrime(4096, Random()).also(after)
}
}
// This just wraps the async function so that when the result is ready resume the coroutine
suspend fun findBigPrime(): BigInteger =
suspendCancellableCoroutine { cont ->
findBigPrimeInNewThread {
cont.resume(it)
}
}