如何使用Kotlin协同程序正确进行阻塞服务呼叫?

时间:2019-08-25 22:29:58

标签: kotlin blocking nonblocking coroutine kotlin-coroutines

我正在处理一个http库(特别是一个用于进行graphql调用的库),它的API仅提供阻塞调用,并且是用Java编写的。

现在,我正在用Kotlin编写应用程序并使用协程库,这让我想知道如何使用协程进行阻塞网络调用。

所以我有这段代码:

class DataService(val client: Client) {
    suspend fun getData(request: Request) {
        // process request

        client.makeServiceCall(...)

        //deal with response
    }
}

class Client() {
    suspend fun makeServiceCall(...) {
        library.query(....) //make a network call using the above mentioned library
    }
}

所以我想知道Client.makeServiceCall()是否应该实际上被标记为挂起函数,因为它实际上并未挂起,仅在进行网络调用时才阻塞。我该如何从DataService.getData()makeServiceCall()进行呼叫,并且仍然遵守结构化并发原则(例如父子协程关系)?

2 个答案:

答案 0 :(得分:2)

因为您使用的api会进行阻塞调用,并不一定意味着您需要遵守该要求。如果您已经在使用Kotlin协程,则可以轻松使用withContext(Dispatchers.IO来要求某个函数在IO线程上运行。您绝对应该这样做以避免挂起UI线程。

    suspend fun makeServiceCall(...) = withContext(Dispatchers.IO) {
        // This code now executes on a background thread and will not block the UI
        library.query(....) //make a network call using the above mentioned library
    }

答案 1 :(得分:1)

withContext(Dispatchers.IO)函数中使用makeServiceCall