簡體   English   中英

取消自定義 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()放在啟動之外,它會立即取消協程而不調用啟動塊代碼。這是預期的嗎?為什么會發生?如果我希望協程在完成執行后結束,應該將取消放在啟動塊末尾的啟動內啟動內的代碼?

更新

根據 Hau Luu 的回答和 Marko Topolnik 的評論,

“在launch結束時,我認為任務完成了,你不需要手動取消Coroutine。”

“一旦你的任務完成,協程就會從 memory 中消失。”

但是在案例 2 中,如果我開始另一個啟動,除非我們像案例 1 中那樣取消第一次啟動內的協程,否則它會被執行。那么,是否可以確定在任務完成后協程會從 memory 中消失,而無需我們手動調用 cancel()? Bcoz 編譯器永遠不會知道哪個是要執行的最后一個啟動,之后它需要結束協程

情況1

scope.launch {
    Log.e("Task","1");
    scope.cancel()
}
scope.launch {
    Log.e("Task","2");
}

僅打印任務 1

案例2

scope.launch {
    Log.e("Task","1");
}
scope.launch {
    Log.e("Task","2");
}

打印任務 1 和 2

您的代碼可以翻譯為自然語言,“在執行 scope.launch 之后立即取消給定的協程”,所以我認為這是預期的行為。

而對於另一個問題,我們只想在執行過程中出現問題時取消協程 - 嘿協程,在執行我給你的任務期間。 如果有錯誤發生。 殺死自己。 所以在啟動結束時,我認為任務完成了,你不需要手動取消協程。

更新:我寫這個作為答案,因為我不能在評論中寫代碼。

CoroutineScope 旨在對創建/啟動/容納協程的 object 的生命周期做出反應。 因此,當您在 CoroutineScope 上調用取消方法時,您將停止一切。 停止不取消。 scope 創建的所有子協程,它們正在執行的所有作業,都取消它們,僅此而已。 工作完成了。 這就是為什么你不能在 scope.cancel 之后開始另一個發射

CoroutineScope 將通過啟動和異步等構建器方法創建並保存對一堆 Corrountine 的引用。 當你想取消一個特定的協程時。 您需要取消構建器返回的作業。 不要取消容納它們的 scope。

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.ZFC35FDC70D5FC69D269Z83A8E2

val job1 = scope.launch{ print('Task 1') }
job1.cancel()
val job2 = scope.launch{ print('Task 2') }

任務 2 將正常打印。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM