首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协同范围、暂停和withContext查询

协同范围、暂停和withContext查询
EN

Stack Overflow用户
提问于 2019-08-15 08:58:13
回答 2查看 1.6K关注 0票数 4

我下面有三个片段

  1. 只是范围发射
代码语言:javascript
复制
    fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
    fun rumMe() = doSomething()
  1. 暂停范围启动
代码语言:javascript
复制
    fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
    suspend fun rumMe() = doSomething()
  1. 使用挂起和withContext启动范围
代码语言:javascript
复制
    fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
    suspend fun rumMe() = withContext(Dispatchers.Default) { doSomething() }

我看到它们在与主线程不同的线程中启动,并且是异步运行的,而不是阻塞主线程。

我想知道他们有什么不同?如果它们都是一样的,那么1是最好的。如果没有,我应该什么时候使用2或3?

我试着读了这个,但是https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761看不清楚

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-15 09:23:45

1和2是相同的。您必须向函数中添加suspend修饰符,只有当它使用协同操作时才能这样做。

第一和第三种情况的区别:

代码语言:javascript
复制
fun main() = CoroutineScope(Dispatchers.IO).launch { 
    // io thead executor
    runMe()
}
// still io thread executor
fun rumMe() = doSomething()

fun main() = CoroutineScope(Dispatchers.IO).launch { 
    // io thead executor
    runMe()
}
suspend fun rumMe() = withContext(Dispatchers.Default) { 
    // default/cpu thead executor
    doSomething()
}
票数 3
EN

Stack Overflow用户

发布于 2019-08-19 10:09:32

通过向函数添加suspend修饰符,允许函数使用另一个挂起函数。例如,如果runMe()函数使用挂起延迟,则使该函数可挂起是合理的。请参阅你的第一个协同线文档部分。

悬置函数与普通函数的另一个主要区别是悬置函数可取消。让我们看一下Android示例:

代码语言:javascript
复制
class MyViewModel : BaseViewModel() {
  init {
    viewModelScope.launch {
      val firstPart = loadFirstPartOfData()
      val secondPart = loadSecondPartOfData(firstPart)
      ...
    }
  }

  suspend loadFirstPartOfData() = withContext(Dispatchers.IO) { ... }

  suspend loadSecondPartOfData(firstPartOfData: FirstPartOfData) {
    // some UI thread safe calculations
    return withContext(Dispatchers.IO) {
        // network request here
    }
  }
}

假设视图(Android活动)加载数据以显示它。如果活动在加载数据的第二部分之前关闭,则加载第二部分是浪费的。但是,因为loadSecondPartOfData()函数是挂起的,所以它检查作用域是否是活动的,如果作用域不是活动的,则不会执行该函数。

还请注意函数如何使用withContext(Dispatchers.IO)。函数从viewModelScope.launch调用,默认情况下使用Dispatchers.Main (UI线程),但是从UI线程调用函数是安全的,因为函数显式地选择了执行上下文。在调用函数时不担心当前线程时,编写挂起函数的方法是正确的。是关于你的第三个问题。

在您的示例中,第一个片段可以工作,但是在一个真正的应用程序中,就像往常一样,事情会变得更加复杂。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57507224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档