簡體   English   中英

CoroutineScope(SupervisorJob()) vs 全局 Scope

[英]CoroutineScope(SupervisorJob()) vs Global Scope

這兩者有什么區別?

我正在學習教程,老師說我們需要一個與應用程序一樣長的 scope,使用 SupervisorJob 手動創建了 scope。 GlobalScope 不做同樣的事情嗎?

我對此進行了研究,但找不到合適的解釋。 謝謝。

這兩個具體例子的區別在於 GlobalScope 不能取消,而另一個可以。 當您在使用CoroutineScope()構造函數 function 創建的 CoroutineScope 上調用cancel()時,它的所有子協程都會被取消。

如果您嘗試cancel() GlobalScope 將拋出 IllegalStateException,因為它沒有 Job 作為它啟動的協程的父級。

當您調用CoroutineScope()而不傳遞 Job 時,它會自動獲得一個通用 Job 作為其協程的父級。 如果其中任何一個子協程失敗,像這樣的通用父 Job 將取消其所有子協程。 如果您明確使用SupervisorJob() ,那么如果它的任何子代失敗,它們不會導致其所有兄弟姐妹被取消。 這是一種類似於 GlobalScope 的行為,因為 GlobalScope 協程沒有兄弟姐妹,它們可能導致通過共享父節點取消。

不鼓勵 GlobalScope 的原因是它沒有監督能力。 它應該只用於應該在應用程序 session 的整個生命周期內運行的協程。 但是,如果您在 Android 上執行不應該取消的重要工作,那么協程無論如何都不是一個好的選擇,因為它們無法處理您的應用程序在后台的情況。 在這些情況下,您應該改用服務或 WorkManager。 因此,GlobalScope 或任何從未取消的 CoroutineScope 的實際合法用例極為罕見。

我認為他們添加@DelicateCoroutinesApi的原因是很多人在濫用 GlobalScope。 (可能是因為他們不幸在關於如何使用協程的初學者文檔中使用了它。)通過使用CoroutineScope(SupervisorJob())CoroutineScope(Dispatchers.IO)等而不是 GlobalScope 來繞過警告是不正確的,因為所做的只是在不改變行為的情況下掩蓋警告,而不是創建一個冗余的 CoroutineScope。 如果您對 GlobalScope 有合法用途,則應使用@OptIn(DelicateCoroutinesApi::class)來消除警告。

暫無
暫無

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

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