I have some simple "hello world" code and i would like some help to know why the last statement printed is NOT this log statement:
Log.v("myFunc", "finished count")
My task is to create a supervisorScope
that waits for all suspend functions to complete and then prints out a message. Here is the code:
suspend fun fun1() {
Log.v("myFunc", "1")
}
suspend fun fun2() {
Log.v("myFunc", "2")
}
suspend fun fun3() {
Log.v("myFunc", "3")
}
suspend fun fun4() {
delay(3000L)
Log.v("myFunc", "4")
}
suspend fun fun5() {
Log.v("myFunc", "5")
}
suspend fun fun6() {
Log.v("myFunc", "6")
}
later on somewhere else i do this:
viewModelScope.launch(dispatchers.IO) {
supervisorScope {
launch { fun1() }
launch { fun2() }
launch { fun3() }
launch { fun4() }
launch { fun5() }
launch { fun6() }
Log.v("myFunc", "finished count")
}
}
and here is the log results:
2022-10-15 19:48:13.722 V/myFunc: 1
2022-10-15 19:48:13.722 V/myFunc: 3
2022-10-15 19:48:13.722 V/myFunc: finished count
2022-10-15 19:48:13.722 V/myFunc: 5
2022-10-15 19:48:13.722 V/myFunc: 6
2022-10-15 19:48:13.723 V/myFunc: 2
2022-10-15 19:48:16.724 V/myFunc: 4
I am very surprised the last result is not "finished count". What am I doing wrong ? Note the function 4 has a delay in it intentionally it should not matter as i still want all functions launched to finish before I print my final statement.
CodePudding user response:
There is no guarantee that the log will be printed the last in that case. To achieve your goal the log should be moved out of the supervisorScope
:
viewModelScope.launch(Dispatchers.IO) {
supervisorScope {
launch { fun1() }
launch { fun2() }
launch { fun3() }
launch { fun4() }
launch { fun5() }
launch { fun6() }
}
Log.v("myFunc", "finished count")
}
In this case the coroutine will wait until supervisorScope
has completed all of its jobs (supervisorScope
returns as soon as the given block and all its child coroutines are completed), and then the log will be printed.