kotlin 当多任务执行时,如何退出协程作用域?

fcg9iug3  于 2023-10-23  发布在  Kotlin
关注(0)|答案(1)|浏览(93)

我正在处理一系列远程API调用任务,并希望使用KotlinCoroutines并行执行它们。每个任务都有不同的执行周期,并在完成时返回结果。
我的目标是,一旦未知数量的任务的总和超过特定值,就退出当前方法。可以让剩余的任务保持运行状态。然而,我目前面临着在Coroutine范围内实现此退出条件的挑战。

fun main(args: Array<String>) {
    runInParallel()
}

fun runInParallel(): Int {
    val threadPool = Executors.newFixedThreadPool(50)
    val scope = CoroutineScope(threadPool.asCoroutineDispatcher())
    var sum = 0

    runBlocking {
        (3..10).forEach{ n ->
            scope.launch {
                val deferredResult1 = async {
                    logTs( "register resultDelay3Deferred")
                    httpCallWithDelay(n)
                }

                val result1 = deferredResult1.await()

                println(result1)
                sum += result1
                println("current sum is $sum")
                if (sum > 10)
                   return sum     // here I cannot return or exit my current method
            }
        }
    }

    println("final sum is $sum")
}

fun httpCallWithDelay(delay: Int): Int {
    Thread.sleep(delay*1000)   // mock the period of API call latency
    return delay
}
bhmjp9jg

bhmjp9jg1#

import kotlinx.coroutines.async
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow

var sum = 0
val totalSum = MutableStateFlow(0)
fun main(args: Array<String>) {
    CoroutineScope(Dispatchers.IO).launch {
        totalSum.collect {
            println("final sum is $sum")

        }
    }
    runBlocking {
        runInParallel()
    }

}

suspend fun runInParallel() {
    coroutineScope {
        (3..10).map { n ->
            async {

                val result = async {
                    httpCallWithDelay(n)
                }.await()
                sum += result
                println("current sum is $sum")
                if (sum > 10) {
                    totalSum.emit(sum)
                    this.cancel()
                }
            }
        }.awaitAll()
    }
}

suspend fun httpCallWithDelay(delayTime: Int): Int {
    delay((delayTime * 1000).toLong())
    return delayTime
}

相关问题