【发布时间】:2019-09-19 12:24:57
【问题描述】:
我想使用协程并行执行多个作业。这是我想出的一段代码。
我有 2 个疑问:
如何确保在调用者线程中发生完成回调?
代码变得更像我以前使用的回调模式 正常线程。请建议更改设计以实现 协程可读性优势。
class ParallelExecutor {
suspend fun <OUTPUT> execute(
jobs: List<suspend () -> OUTPUT>,
onTimeout: (jobIndex: Int) -> OUTPUT,
onFailure: (jobIndex: Int, exception: Throwable) -> OUTPUT,
onCompletion: suspend (jobIndex: Int, result: OUTPUT) -> Unit,
timeout: Long,
onFullCompletion: suspend () -> Unit = {},
invokeDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
withContext(invokeDispatcher) {
var counter = 0
val listenJobs = mutableListOf<Deferred<OUTPUT>>()
jobs.forEachIndexed { index, job ->
val listenJob = async {
try {
job()
} catch (e: Exception) {
onFailure(index, e)
}
}
listenJobs.add(listenJob)
}
listenJobs.forEachIndexed { index, job ->
launch {
val output = try {
withTimeout(timeout) {
job.await()
}
} catch (e: TimeoutCancellationException) {
onTimeout(index)
}
onCompletion(index, output)
if (++counter == listenJobs.size) {
onFullCompletion()
}
}
}
}
}
}
【问题讨论】:
-
这是一种非常...不同的协程使用方式,您确定要使用协程来实现吗?我不认为这需要如此通用。
-
这个函数是如何在你的代码中使用的?这样可以更轻松地提出建议。
-
您希望在“调用者线程”或“调用者调度程序”中调用完成回调? (线程可能是不可能的)。
-
@DominicFischer 我想同时开始多个相同工作的地方很少。这段代码在所有这些地方都是多余的。所以我把它移到了外面。这就是我达到这个目的的方式。