0

Android Studio 3.6

I need next:

  1. List of strings (file names)
  2. Each method doSomeLongOperation(fileName) must be executed in parallel and independently. E.g. method doSomeLongOperation(fileName1) MUST NOT wait for a response from the method doSomeLongOperation(fileName2).
  3. The result of every doSomeLongOperation(fileName) is different and must be add to list

So suppose the duration of doSomeLongOperation(fileName) is 5 seconds.

So if I start on 12:00:00 then all must be finish on 12:00:05

So here snippet:

 suspend fun testParallel(filesList: List<String>) =
            withContext(Dispatchers.IO) {
                Debug.d(TAG, "testParallel: start, filesList = $filesList")
                val resultList = mutableListOf<Deferred<Int>>()
                filesList.forEach({
                    val result = async { doSomeLongOperation(it) }
                    resultList.add(result)
                })
                Debug.d(TAG, "testParallel: resultList = ${resultList.awaitAll()}")
            }

        suspend fun doSomeLongOperation(fileName: String): Int {
            //val duration = 1000L * Random().nextInt(20)
            val duration = 1000L * 5
            Debug.d(TAG, "doSomeLongOperation: START, fileName = $fileName, duration = $duration")
            delay(duration)
            val random = Random().nextInt(100)
            Debug.d(
                TAG,
                "doSomeLongOperation: FINISH, fileName = $fileName, duration = $duration, random = $random"
            )
            return random
        }

and here output:

01-28 17:57:19.662  testParallel: start, filesList = [file_1, file_2, file_3, file_4, file_5,
01-28 17:57:19.670  doSomeLongOperation: START, fileName = file_1, duration = 5000           
01-28 17:57:19.671  doSomeLongOperation: START, fileName = file_2, duration = 5000           
01-28 17:57:19.678  doSomeLongOperation: START, fileName = file_4, duration = 5000           
01-28 17:57:19.684  doSomeLongOperation: START, fileName = file_3, duration = 5000           
01-28 17:57:19.684  doSomeLongOperation: START, fileName = file_5, duration = 5000           
01-28 17:57:19.685  doSomeLongOperation: START, fileName = file_7, duration = 5000           
01-28 17:57:19.685  doSomeLongOperation: START, fileName = file_6, duration = 5000           
01-28 17:57:19.685  doSomeLongOperation: START, fileName = file_8, duration = 5000           
01-28 17:57:19.685  doSomeLongOperation: START, fileName = file_9, duration = 5000           
01-28 17:57:19.685  doSomeLongOperation: START, fileName = file_10, duration = 5000

...

01-28 17:57:24.674  doSomeLongOperation: FINISH, fileName = file_1, duration = 5000, random = 0
01-28 17:57:24.675  doSomeLongOperation: FINISH, fileName = file_2, duration = 5000, random = 17
01-28 17:57:24.678  doSomeLongOperation: FINISH, fileName = file_4, duration = 5000, random = 16
01-28 17:57:24.684  doSomeLongOperation: FINISH, fileName = file_3, duration = 5000, random = 75
01-28 17:57:24.684  doSomeLongOperation: FINISH, fileName = file_5, duration = 5000, random = 19
01-28 17:57:24.685  doSomeLongOperation: FINISH, fileName = file_7, duration = 5000, random = 59
01-28 17:57:24.685  doSomeLongOperation: FINISH, fileName = file_6, duration = 5000, random = 2
01-28 17:57:24.686  doSomeLongOperation: FINISH, fileName = file_8, duration = 5000, random = 38
01-28 17:57:24.686  doSomeLongOperation: FINISH, fileName = file_9, duration = 5000, random = 64
01-28 17:57:24.686  doSomeLongOperation: FINISH, fileName = file_10, duration = 5000, random = 94

01-28 17:57:24.686  testParallel: resultList = [0, 17, 75, 16, 19, 2, 59, 38, 64, 94]

As you can see the process start on 01-28 17:57:19 and ALL METHODS WAS FINISHED AFTER 5 SECONDS at

01-28 17:57:24

And result of every doSomeLongOperation was added to restulList. Nice. It's work fine. To do all of this I use Kotlin's method: async

The question is:

Is this a right way to do this by Kotlin's coroutines?

Alexei
  • 14,350
  • 37
  • 121
  • 240
  • 1
    yes it is :-) what more where you thinking? – Blundell Jan 28 '20 at 16:09
  • @Blundell I found in Kotlin this: GlobalScope.async{...}. What is a different from simple async{} ? – Alexei Jan 28 '20 at 16:11
  • 1
    simple `async` is for running a suspening function, `GlobalScope.async{}` (if my own understanding is correct) is for starting a new CoRoutine Scope (aka like starting a Thread). Don't quote me :) but didn't want to not reply :D – Blundell Jan 28 '20 at 16:13
  • `async` is always `async`, it is an extension function on `CoroutineScope` so in fact you're already calling it on some scope, which is the implicit `this`, referring to the scope of `withContext`. – Marko Topolnik Jan 28 '20 at 20:12
  • 1
    It is correct, you start all asyncs without waiting, keep reference to Deferred result, then await all those Deferred results to get actual results. (GlobalScope.async vs myScope.async is just trying the coroutine to some scope, so you can cancel them at once) – Jemshit Jan 30 '20 at 13:06
  • @a_subscriber found this good explanation and thought of you :-) https://stackoverflow.com/a/59387148/413127 – Blundell Feb 12 '20 at 14:38

0 Answers0