为什么withContext之后的行被阻塞?

时间:2019-08-23 12:15:49

标签: android kotlin kotlin-coroutines

我想知道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

1 个答案:

答案 0 :(得分:2)

如果查看 File "C:\home\app\routes.py", line 187, in send_reset_email) File "C:\home\app\routes.py", line 169, in create_message return {'raw': base64.urlsafe_b64encode(message.as_string())} File "C:\home\b\base64.py", line 118, in urlsafe_b64encode return b64encode(s).translate(_urlsafe_encode_translation) File "C:\home\b\base64.py", line 58, in b64encode hencoded = binascii.b2a_base64(s, newline=False) 的定义,您会注意到它是一个暂停函数:

withContext

暂停功能由Kotlin编译器转换为延续。您可以将其视为回调链。

所以,您会得到类似这样的信息:

public suspend fun <T> withContext

现在您可以更清楚地看到, 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() } 完成之前,什么都不会发生。