使用Kotlin协程,我需要在一个try
块中同时并行运行两个I/O工作,而不会相互阻塞。
如果任何工作失败,那么应该在单个catch
块中捕获它。
两个操作是:
a)以10秒的间隔连续ping服务器。
B)使用okhttp进行网络呼叫。
我需要在suspend
函数中介绍这两个操作。PSB代码:
suspend fun sendAllRequests() {
try {
pingServer()
makeNetworkCall()
} catch(exception: CustomException) {
// Do some other work and throw exception to UI
throw RuntimeException("Custom Error")
}
}
suspend fun pingServer() {
job = GlobalScope.launch {
while(true) {
delay(10000) {
if(isPingSuccess) {
Log("Connection active")
} else {
Log("Connection Inactive")
job.cancel()
throw RuntimeException("Ping failed")
}
}
}
}
suspend fun makeNetworkCall() {
//This is a pseudo code just for explanation
okhttp.newCall().await()
onFailure -> throw Exception
}
上述方法的挑战在于,它只启动函数pingServer()
中存在的逻辑。
即函数makeNetworkCall()
从未被触发。
如果我把第一个函数 Package 在一个新的协程作用域中,如下所示:
那么这两个作业都能正常工作,但是pingServer()
抛出的异常永远不会被catch
块捕获。
try {
// With below logic, both functions are triggered
scope.launch { pingServer() }
makeNetworkCall()
} catch {
// but pingServer() failure never reaches here
// and makeNetworkCall() failure is properly captured here
}
如何并行运行上述两个长时间运行的任务,而不会相互阻塞?
我如何确保如果其中任何一个抛出异常,那么它会在上面所示的同一个catch
块中被捕获?
1条答案
按热度按时间bq3bfh9z1#
基于this article,实现您所追求的目标的一种简单方法是不使用
launch
,而是使用async
。然后,您可以运行makeNetworkCall()
,然后在异步延迟对象上运行await
,在那里捕获异常就像这样:
还请注意:
1.你在另一个协程上启动或异步并不意味着代码在后台线程上运行,你需要将你的协程启动到另一个调度程序(例如:Dispatchers.IO)
1.避免使用GlobalScope,这样做很容易造成内存泄漏。创建您自己的作用域,或者如果您使用Android,请尝试使用AppComponents作用域,如viewModelScope或lifecycleScope