取消自定义 CoroutineScope
Cancelling custom CoroutineScope
val scope = CoroutineScope(
Job() + Dispatchers.Main
)
scope.launch {
beforeExecute()
val result = withContext(dispatcher) { doInBackground(*params) }
if (!isCancelled) {
postExecute(result)
} else {
cancelled(result)
}
status = Status.FINISHED
}
scope.cancel()
如果我把 scope.cancel()
放在启动之外,它会立即取消协程而不调用启动块 code.Is 这是预期的?为什么会发生?如果我想取消,应该在启动块结束时将其放置在启动内协程在启动内完成代码执行后结束?
更新
根据 Hau Luu 的回答和 Marko Topolnik 的评论,
”at the end of launch, I think the task is done and you don't need to
manually cancel the Coroutine.”
和
“Once your task is done, the coroutine disappears from memory.”
但是在案例 2 中,如果我启动另一个启动,它将被执行,除非我们像案例 1 那样取消第一次启动中的协程。
那么是否可以确定在任务完成后协程从内存中消失而不需要我们手动调用 cancel()?Bcoz 编译器永远不会知道哪个是最后一次启动,之后它需要结束协程
案例一
scope.launch {
Log.e("Task","1");
scope.cancel()
}
scope.launch {
Log.e("Task","2");
}
只打印任务 1
案例二
scope.launch {
Log.e("Task","1");
}
scope.launch {
Log.e("Task","2");
}
任务 1 和 2 都被打印
您的代码可以翻译成自然语言“在 scope.launch 执行后立即取消给定的协程”,所以我认为这是预期的行为。
而对于另一个问题,我们只想在执行过程中出现错误时取消协程 - 嘿协程,在执行我给你的任务期间。如果有什么错误发生。杀了你自己。所以在启动结束时,我认为任务完成了,你不需要手动取消Coroutine。
更新:我写这个作为答案,因为我不能在评论中写代码。
CoroutineScope 旨在对 create/start/house 协程对象的生命周期作出反应。因此,当您在 CoroutineScope 上调用 cancel 方法时,您将停止一切。停止不取消。作用域创建的所有子协程,它们正在执行的所有作业,全部取消,仅此而已。工作完成了。这就是为什么您无法在 scope.cancel
之后再次启动的原因
CoroutineScope 将通过启动和异步等构建器方法创建并保存对一堆 Corrountine 的引用。当你想取消一个特定的协程时。您需要取消构建器返回的作业。不取消容纳它们的范围。
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html
val job1 = scope.launch{ print('Task 1') }
job1.cancel()
val job2 = scope.launch{ print('Task 2') }
任务 2 将正常打印。
val scope = CoroutineScope(
Job() + Dispatchers.Main
)
scope.launch {
beforeExecute()
val result = withContext(dispatcher) { doInBackground(*params) }
if (!isCancelled) {
postExecute(result)
} else {
cancelled(result)
}
status = Status.FINISHED
}
scope.cancel()
如果我把 scope.cancel()
放在启动之外,它会立即取消协程而不调用启动块 code.Is 这是预期的?为什么会发生?如果我想取消,应该在启动块结束时将其放置在启动内协程在启动内完成代码执行后结束?
更新
根据 Hau Luu 的回答和 Marko Topolnik 的评论,
”at the end of launch, I think the task is done and you don't need to manually cancel the Coroutine.”
和
“Once your task is done, the coroutine disappears from memory.”
但是在案例 2 中,如果我启动另一个启动,它将被执行,除非我们像案例 1 那样取消第一次启动中的协程。 那么是否可以确定在任务完成后协程从内存中消失而不需要我们手动调用 cancel()?Bcoz 编译器永远不会知道哪个是最后一次启动,之后它需要结束协程
案例一
scope.launch {
Log.e("Task","1");
scope.cancel()
}
scope.launch {
Log.e("Task","2");
}
只打印任务 1
案例二
scope.launch {
Log.e("Task","1");
}
scope.launch {
Log.e("Task","2");
}
任务 1 和 2 都被打印
您的代码可以翻译成自然语言“在 scope.launch 执行后立即取消给定的协程”,所以我认为这是预期的行为。
而对于另一个问题,我们只想在执行过程中出现错误时取消协程 - 嘿协程,在执行我给你的任务期间。如果有什么错误发生。杀了你自己。所以在启动结束时,我认为任务完成了,你不需要手动取消Coroutine。
更新:我写这个作为答案,因为我不能在评论中写代码。
CoroutineScope 旨在对 create/start/house 协程对象的生命周期作出反应。因此,当您在 CoroutineScope 上调用 cancel 方法时,您将停止一切。停止不取消。作用域创建的所有子协程,它们正在执行的所有作业,全部取消,仅此而已。工作完成了。这就是为什么您无法在 scope.cancel
之后再次启动的原因CoroutineScope 将通过启动和异步等构建器方法创建并保存对一堆 Corrountine 的引用。当你想取消一个特定的协程时。您需要取消构建器返回的作业。不取消容纳它们的范围。
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html
val job1 = scope.launch{ print('Task 1') }
job1.cancel()
val job2 = scope.launch{ print('Task 2') }
任务 2 将正常打印。