gpt4 book ai didi

Kotlin 协程 : what's the diffrence between using NonCancellable and a standalone new Job

转载 作者:行者123 更新时间:2023-12-02 13:15:31 24 4
gpt4 key购买 nike

在协程中,当我想保护一段代码不被取消时,我应该将 NonCancellable 添加到上下文中:

@Test
fun coroutineCancellation_NonCancellable() {
runBlocking {
val scopeJob = Job()
val scope = CoroutineScope(scopeJob + Dispatchers.Default + CoroutineName("outer scope"))
val launchJob = scope.launch(CoroutineName("cancelled coroutine")) {
launch (CoroutineName("nested coroutine")) {
withContext(NonCancellable) {
delay(1000)
}
}
}
scope.launch {
delay(100)
launchJob.cancel()
}
launchJob.join()
}
}
上面的单元测试将需要大约 1.1 秒的时间来执行,即使长时间运行的协程在 100 毫秒后被取消。这就是 NonCancellable 的效果,我理解这一点。
但是,以下代码在功能上似乎是等效的:
@Test
fun coroutineCancellation_newJobInsteadOfNonCancellable() {
runBlocking {
val scopeJob = Job()
val scope = CoroutineScope(scopeJob + Dispatchers.Default + CoroutineName("outer scope"))
val launchJob = scope.launch(CoroutineName("cancelled coroutine")) {
launch (CoroutineName("nested coroutine")) {
withContext(Job()) {
delay(1000)
}
}
}
scope.launch {
delay(100)
launchJob.cancel()
}
launchJob.join()
}
}
我试图在取消、错误处理和一般功能方面找到这两种方法之间的任何功能差异,但到目前为止我没有发现。目前,看起来 NonCancellable 在框架中只是为了便于阅读。
现在,可读性很重要,所以我更喜欢在代码中使用 NonCancellable。但是, its documentation听起来它实际上与普通的 Job 有点不同,所以我想详细了解这方面。
所以,我的问题是:这两种方法之间是否有任何功能差异(即如何修改这些单元测试以产生不同的结果)?
编辑:
按照路易斯的回答,我测试了“使清理不可取消”的场景,在这种情况下,Job() 也类似于 NonCancellable。在下面的示例中,单元测试将运行超过 1 秒,即使协程在 200 毫秒后被取消:
@Test
fun coroutineCancellation_jobInsteadOfNonCancellableInCleanup() {
runBlocking {
val scope = CoroutineScope(Job() + Dispatchers.Default + CoroutineName("outer scope"))
val launchJob = scope.launch(CoroutineName("test coroutine")) {
try {
delay(100)
throw java.lang.RuntimeException()
} catch (e: Exception) {
withContext(Job()) {
cleanup()
}
}
}
scope.launch {
delay(200)
launchJob.cancel()
}
launchJob.join()
}
}

private suspend fun cleanup() {
delay(1000)
}

最佳答案

NonCancellable不响应取消,而 Job()做。NonCancellable实现 Job以自定义方式,它与 Job() 的行为不同那是使用可取消的实现。cancel()NonCancellable是无操作的,不像 Job()它将取消任何子协程,并且子协程中的任何崩溃都会传播到该父协程 Job .

关于Kotlin 协程 : what's the diffrence between using NonCancellable and a standalone new Job,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64389648/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com