在阅读Kotlin文档之后,我想出了以下代码(该代码不起作用-见下文)重复一个函数调用,直到它返回true或达到超时为止。
我想暂停执行,直到此代码块达到超时或成功-不应异步执行。
Log.d(TAG, "This is the last line to be logged")
runBlocking {
Log.d(TAG, "this line is never logged")
try {
withTimeout(timeoutMsL) {
while ((isActive) && (!success)) {
success = doSomething()
}
}
}
catch (ex: TimeoutCancellationException) {
Log.d(TAG, "this line is never logged either")
doSomethingElse()
}
}
timeoutMsL
是一个Long
,典型值为50毫秒。
该代码是通过JNI从C ++调用的。当我运行它
我读到应该避免使用runBlocking
,但是您也必须从现有的协程调用withTimeout
。
如果我使用普通的协程,则在达到超时/成功之前,将继续执行调用函数-我需要防止这种情况的发生。
如何用Kotlin进行编码?
答案 0 :(得分:1)
您的问题可能出在doSomething()
。 Kotlin的协程实现在很大程度上依赖于合作执行,在合作执行中,子协程检查标志以查看其是否已取消(就像withTimeout()
那样)。这意味着外部协程将暂停直到它们确认子协程已结束,从而阻塞整个功能。
如果doSomething
从不挂起并且从不检查它是否仍处于活动状态,则无论外部情况如何,它都将一直运行到完成。
要解决此问题,有两种选择:
doSomething()
一个suspend
函数,并定期yield()
或ensureActive()
暂停以响应取消。withContext(Dispatchers.IO)
)的调度程序上执行该命令。