Parallel decomposition of independent async tasks with kotlin coroutines
我正在尝试并行运行多个任务,但是这些任务是独立的,因此如果子协程之一失败,我也不希望其兄弟姐妹或父母也失败。在下面的代码中,我使用coroutineScope创建了一个新范围,在这些范围内运行这些任务,并在发送其ID和应等待的延迟时间时启动了5个异步任务。第二个协程抛出异常。在这种情况下,代码执行了我想要的操作,它计算成功完成的作业和失败的作业的总和,返回0。
但是,我阅读的内容是,kotlinx库中还有一个supervisorScope,而不是coroutineScope(如果不处理异常,它会取消父/兄弟姐妹),而不是其他任务,应该优先使用supervisorScope。我不确定为什么要随着使用coroutineScope获得想要的结果而更改为使用supervisorScope。
问题1:如果我要更改为supervisorScope,我的异步块中是否应该有所更改?
问题2:是否可以在async块中捕获任何异常,并且不让任何内容传播到其父级?我知道您也可以在.await()阶段捕获异常,但这是应该这样做的方式吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | runBlocking { coroutineScope { val job1 = async<Int> { try { request(1, 1000) } catch (e: Exception) { println("Job 1 failed with $e") 0 } } val job2 = async<Int> { try { request(2, 2000) throw Exception("cancelling Job 2") } catch (e: Exception) { println("Job 2 failed: $e") 0 } } val job3 = async { try { request(3, 3000) } catch (e: Exception) { println("Job 3 failed with $e") 0 } } val job4 = async { try { request(4, 4000) } catch (e: Exception) { println("Job 4 failed with $e") 0 } } val job5 = async { try { request(5, 5000) } catch (e: Exception) { println("Job 5 failed with $e") 0 } } val result = job1.await() + job2.await() + job3.await() + job4.await() + job5.await() println(result.toString()) } println("Finished") } |
1 2 3 4 5 6 | suspend fun request(id: Int, time: Long): Int { println("Job $id started") delay(time) println("Job $id finished") return id } |
所有协程运行完成的原因是您在作业2本身中
但是,如果删除job2中的
这是因为
解答1:不使用
解答2:当然可以允许在