[英]CoroutineScope cancelation
我完全了解suspendCoroutine 和suspendCancellableCoroutine 在我的示例中是如何工作的。 但我想知道為什么在我調用 viewScope.cancel() 之后執行println("I finished") (第 13 行 - viewscope 塊中的第二行)。 我可以在此行之前使用 isActive 標志修復它,但我不想檢查每一行。 我在那里想念什么。 我如何也可以取消 scope? 謝謝
import kotlinx.coroutines.*
import java.lang.Exception
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
fun main() {
val parentJob = Job()
val viewScope = CoroutineScope(Dispatchers.IO + parentJob)
viewScope.launch {
println(tryMe())
println("I finished")
}
Thread.sleep(2000)
viewScope.cancel()
Thread.sleep(10000)
}
suspend fun tryMe() = suspendCoroutine<String> {
println("I started working")
Thread.sleep(6000)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
suspend fun tryMe2() = suspendCancellableCoroutine<String> {
println("I started working")
Thread.sleep(6000)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
suspend fun tryMe3() = suspendCancellableCoroutine<String> {
it.invokeOnCancellation { println("I canceled did you heard that ?") }
println("I started working")
Thread.sleep(6000)
if (it.isActive)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
如果我們只是調用cancel
,並不意味着協程工作就會停止。 如果您正在執行一些相對繁重的計算,例如從多個文件中讀取,則沒有什么可以自動阻止您的代碼運行。 一旦調用了job.cancel
,我們的協程就會轉到 Canceling state。
取消協程代碼需要協同
您需要確保您正在實施的所有協程工作都與取消合作,因此您需要定期或在開始任何長時間運行的工作之前檢查取消。 例如,如果您正在從磁盤讀取多個文件,則在開始讀取每個文件之前,請檢查協程是否被取消。 像這樣,您可以避免在不再需要時進行 CPU 密集型工作。
kotlinx.coroutines
中的所有掛起函數都是可取消的: withContext
、 delay
等。因此,如果您使用其中任何一個,則無需檢查取消並停止執行或拋出CancellationException
。 但是,如果您不使用它們,請通過檢查job.isActive
或ensureActive()
使您的協程代碼協作
如果您希望在協程被取消時不執行該語句,則應在println("I finished")
之前檢查協程是否仍處於活動狀態,如下所示:
if (isActive)
println("I finished")
協程不保證在另一個線程上調度。 因此,雖然線程提供了中止的方法,它在運行時的系統級或用戶級實現(例如 JVM 或 ART),但無論如何都不能取消不受線程支持的協程,因為唯一可以做的就是拋出一個異常,但這會中止整個當前執行上下文(即線程),其他協程可能正在運行。
其他答案談論繁重的計算,但這顯然是錯誤的。 無論你在做什么,無論計算量是否繁重——協程都不能被強行取消; 它們的取消只是一個被取消的請求,由協程主體使用CoroutineScope
屬性isActive
來處理取消請求,它會得到一個 boolean 指示協程正在進行的工作是否應該繼續,如果為true
; 或被取消,如果false
。
使用 suspendCancellableCoroutine 正在按預期工作。 suspendCoroutine 不檢查 coroutineScope 的取消 state(內部使用 safeContinuation),而 suspendCancellableCoroutine 通過 CancellableContinuationImpl 檢查取消並取消恢復操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.