Reputation: 103
I need to iterate 100's of ids in parallel and collect the result in list. I am trying to do it in following way
val context = newFixedThreadPoolContext(5, "custom pool")
val list = mutableListOf<String>()
ids.map {
val result:Deferred<String> = async(context) {
getResult(it)
}
//list.add(result.await()
}.mapNotNull(result -> list.add(result.await())
I am getting error at
mapNotNull(result -> list.add(result.await())
as await method is not available. Why await is not applicable at this place? Instead commented line
//list.add(result.await()
is working fine.
What is the best way to run this block in parallel using coroutine with custom thread pool?
Upvotes: 3
Views: 341
Reputation: 28332
Generally, you go in the right direction: you need to create a list of Deferred
and then await()
on them.
If this is exactly the code you are using then you did not return anything from your first map { }
block, so you don't get a List<Deferred>
as you expect, but List<Unit>
(list of nothing). Just remove val result:Deferred<String> =
- this way you won't assign result to a variable, but return it from the lambda. Also, there are two syntactic errors in the last line: you used ()
instead of {}
and there is a missing closing parenthesis.
After these changes I believe your code will work, but still, it is pretty weird. You seem to mix two distinct approaches to transform a collection into another. One is using higher-order functions like map()
and another is using a loop and adding to a list. You use both of them at the same time. I think the following code should do exactly what you need (thanks @Joffrey for improving it):
val list = ids.map {
async(context) {
getResult(it)
}
}.awaitAll().filterNotNull()
Upvotes: 3