如何使用 Kotlin 协程正确进行阻塞服务调用?

cha*_*onk 4 nonblocking blocking coroutine kotlin 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Ome*_*142 5

因为您使用的 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
    }
Run Code Online (Sandbox Code Playgroud)