我正在使用一些不能同时运行的库。这意味着
fun callMyLib(cmd: String, listener: MyLibListener): Long
在通知listener
操作完成之前,无法再次调用。否则会引发异常。
我将这个lib与协程一起使用:
object MyLibRunner {
suspend fun runMyLib(cmd: String): Result {
return suspendCancellableCoroutine { continuation ->
val executionId = callMyLib(cmd, object : MyLibListener {
override fun onSuccess(result: Result) {
continuation.resume(result)
}
override fun onError(e: Exception) {
continuation.resumeWithException(e)
}
})
continuation.invokeOnCancellation { cancelMyLib(executionId) }
}
}
}
我还有一个类,负责为lib准备参数。我试图使该类的所有调用者都形成一个队列,在队列中他们等待上一个作业的完成。
object MyLibEditor {
private val parentJob = SupervisorJob()
suspend fun doSomething(... some args ...): Result {
val id = Random.nextInt()
Log.d(TAG, "#operation $id: join()")
val job = Job(parentJob)
parentJob.children.forEach { if (it != job) it.join() }
...
// prepare command line
...
val cmd = ...
Log.d(TAG, "#operation $id: runMyLib()")
val result = withContext(job) { MyLibRunner.runMyLib(cmd) }
job.complete()
Log.d(TAG, "#operation $id: Done.")
return result
}
}
但是这种方法似乎行不通。在日志中,我看到:
#operation 1: join()
#operation 2: join()
#operation 3: join()
#operation 1: runMyLib()
#operation 1: Done.
似乎第一个操作没有等待,因为没有什么可等待的。但是其他所有操作都将无限期等待。
我做错了什么?如何实现doSomething()
方法的所有其他调用者将等待上一个调用者的完成才能继续?