首页 > 解决方案 > 为什么 withContext 后面的行被阻塞了?

问题描述

我想知道withContext(注意:Dispatchers.IO作为它的第一个参数)之后的行是如何被阻塞的。

看来它们在不同的线程上,但我想知道协程如何按顺序执行它们。

fun deleteAll() {
     viewModelScope.launch {
         Log.d("tag", "Outside withContext(start): " + Thread.currentThread().name)
         withContext(Dispatchers.IO) {
            Log.d("tag", "Deleting....: " + Thread.currentThread().name)
            delay(3_000)
            Log.d("tag", "Done deleting.")
         }
         Log.d("tag", "Outside withContext(end): " + Thread.currentThread().name)
     }
}

输出:

ViewModel deleteAll returning
Outside withContext(start): main
Deleting....: DefaultDispatcher-worker-5
Done deleting.
Outside withContext(end): main

标签: androidkotlinkotlin-coroutines

解决方案


如果您查看 的定义withContext,您会注意到它是一个挂起函数:

public suspend fun <T> withContext

Kotlin 编译器将挂起函数转换为延续。您可以将其视为回调链。

所以,你会得到这样的东西:

    fun a() {
        Log.d("tag", "Outside withContext(start): " + Thread.currentThread().name)
        fun b() {
            withContext(Dispatchers.IO) {
                Log.d("tag", "Deleting....: " + Thread.currentThread().name)
                delay(3_000)
                Log.d("tag", "Done deleting.")
            }
            fun c() {
                Log.d("tag", "Outside withContext(end): " + Thread.currentThread().name)
            }
        }()
    }()

现在您可以更清楚地看到,c()无法执行,直到b()完成。

另一种思考方式是查看以下代码withContext

...
  block.startCoroutineCancellable(coroutine, coroutine)
  coroutine.getResult()
}

coroutine.getResults()完成之前,不会发生其他任何事情。


推荐阅读