英文:
how to continue execution in coroutines when one of the childs fails
问题
我有一个带有两个子协程的作用域。
如果其中一个子协程“崩溃”或抛出异常,我希望另一个子协程能够继续执行。
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
launch() {
repeat(25) {
println("子协程 1 $it")
delay(25)
}
}
launch {
repeat(20) {
println("子协程 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
}
job.join()
println("主程序完成")
}
我想实现的是,如果子协程 2 抛出异常,我希望子协程 1 能够继续执行,直到完成其工作。
英文:
I have a scope with two child coroutines inside it
If one of the child "crasches" or throw an exception i want the another child to continue execution
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
launch() {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
launch {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
}
job.join()
println("Main finished")
}
What i want to achieve is that if child two throws en exception, i want child one to continue until it finishes is job.
答案1
得分: 2
最简单的方法来解决这个问题不是使用supervisorScope
或类似的东西,而是简单地捕获并处理异常。
val job = scope.launch {
launch() {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
launch {
try {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
} catch (e : Exception) {
// 适当记录异常
}
}
}
英文:
The simplest way to address this isn't to use a supervisorScope or anything of the sort, but simply to catch and handle the exception.
val job = scope.launch {
launch() {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
launch {
try {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
} catch (e : Exception) {
// log the exception appropriately
}
}
}
</details>
# 答案2
**得分**: 1
Wrap the children in a `supervisorScope`:
```kotlin
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
supervisorScope {
launch {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
launch {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
}
}
job.join()
println("Main finished")
}
Another option is to use an external scope that uses a SupervisorJob to run the other coroutines, but then they are no longer children of this coroutine. You need to join them manually since they are not children. So usually this is not the way you want to do it.
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
val job1 = scope.launch {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
val job2 = scope.launch {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
job1.join()
job2.join()
}
job.join()
println("Main finished")
}
英文:
Wrap the children in a supervisorScope
:
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
supervisorScope {
launch {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
launch {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
}
}
job.join()
println("Main finished")
}
Another option is to use an external scope that uses a SupervisorJob to run the other coroutines, but then they are no longer children of this coroutine. You need to join them manually since they are not children. So usually this is not the way you want to do it.
suspend fun main() {
val context = Dispatchers.Default + SupervisorJob()
val scope = CoroutineScope(context = context)
val job = scope.launch {
val job1 = scope.launch {
repeat(25) {
println("child 1 $it")
delay(25)
}
}
val job2 = scope.launch {
repeat(20) {
println("child 2 $it")
delay(18)
if (it == 16)
throw Exception("aaa")
}
}
job1.join()
job2.join()
}
job.join()
println("Main finished")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论