withContext和suspendCancellableCoroutine之间的区别

时间:2020-05-13 13:09:18

标签: kotlin kotlin-coroutines

我是协程新手

这是一个受欢迎的示例:

suspend fun findBigPrime(): BigInteger =
    withContext(Dispatchers.IO) {
        BigInteger.probablePrime(4096, Random()))
    }

但是,它也可以写为:

suspend fun findBigPrime(): BigInteger =
    suspendCancellableCoroutine {
        it.resume(BigInteger.probablePrime(4096, Random()))
    }

真正的区别是什么?

2 个答案:

答案 0 :(得分:3)

真正的区别是什么?

实际上几乎没有任何关系。

suspendCancellableCoroutine {
    it.resume(BigInteger.probablePrime(4096, Random()))
}

除了在简单的直接调用之上增加无用的开销之外,这什么都不做

BigInteger.probablePrime(4096, Random())

如果您仍在suspendCancellableCoroutine块中继续执行继续操作,协程根本不会暂停。

withContext(Dispatchers.IO) {
    BigInteger.probablePrime(4096, Random()))
}

这将暂停协程并在另一个线程上启动内部协程。内部协程完成后,它将恢复当前的协程并显示结果。

答案 1 :(得分:0)

这里使用suspendCancellableCoroutine是“大号”。

withContext更改了将在其上运行块(协程)的上下文,在此,将协程分配给指定线程的Dispatcher被覆盖。尽管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)
        }
    }