android - 为什么 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
解决方案
如果您查看 的定义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()
完成之前,不会发生其他任何事情。
推荐阅读
- xcode-cloud - Xcode 云数据中心位置
- wordpress - WPLMS课程购买条件
- oracle - Oracle REGEXP_LIKE 忽略 CASE SENSITIVITY
- active-directory - AD 到 Keycloak - 如何生成 uuid(v4) 作为用户名而不是 objectGUID?
- r - 无法编译 Rmd 文件并出现“找不到对象‘输出’”错误
- sql-server - SQL Server 中的函数需要在 Power BI 中具有可选参数
- python - 使用 Google Sheets 或 Python 对有向图(或矩阵)进行聚类
- c - 一个函数能知道是什么调用它吗?
- javascript - 那些是什么 (); 在javascript代码的末尾?
- spock - Spock中如何使用jmockit来测试静态方法返回多个不同的值?