Kotlin withTimeout 不会取消后台线程上的 okhttp 调用

问题描述 投票:0回答:1

我正在尝试实现网络请求超时(使用 okhttpclient),但没有在 OkHttp 客户端上设置

connectTimeout()
参数。

我是这样做的:

CoroutineScope(Dispatchers.IO).launch {
val res = fetcherUseCase
.fetchData()

}

用例类:

    override suspend fun fetchData(): SomeResultObject {
        val res = fetcher.fetchData()
        return when (res) {
            is Failure -> Result.Failure(res.error)
            is Loading -> { Result.Loading }
            is Success -> Result.Success(res.result)
        }

    }

最后这是获取器:

    suspend fun fetchData(): Result {
        var url = ""
        try {

            .......

            val call = NetworkProvider.okHttpClient.newCall(request)

            url = call.request().toString()

            val d = runBlocking { async { call.execute() } }
            
            Log.d("---", "Here 1")
            val response = withTimeout(1500L) {
                d.await()
            }

        } catch (ex: TimeoutCancellationException) {
             Log.d("---", "Here 2")
        }
        return Result.Loading
    }

但这行不通。我预计它会在 1.5 秒后抛出异常,但网络请求只是继续,Here 2 永远不会打印。

我在这里缺少什么?!

提前致谢

android kotlin kotlin-coroutines
1个回答
0
投票

切勿在您的应用程序中使用

runBlocking
。来自文档

它旨在将常规阻塞代码桥接到以挂起风格编写的库,以在

main
函数和测试中使用。

你没有 main 函数,它也不是一个测试(因为你应该实际使用

runTest
并且不要使用 from
runBlocking
)。

而不是这个:

val d = runBlocking { async { call.execute() } }

Log.d("---", "Here 1")
val response = withTimeout(1500L) {
    d.await()
}

您可以简单地使用这个:

val response = withTimeout(1500L) {
    call.execute()
}
© www.soinside.com 2019 - 2024. All rights reserved.