Home > Enterprise >  Kotlin coroutines supervisorScope - how to make it wait until all launches complete
Kotlin coroutines supervisorScope - how to make it wait until all launches complete

Time:10-16

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.

  • Related