G00fY
G00fY

Reputation: 5297

Handling Sequences in Coroutines

I'm trying to use a Sequence (e.g. FileTreeWalk returned from File.walk) inside a coroutine, but my implementation keeps blocking the ui thread.

Is there a good way to handle Sequences and mapping the items within coroutines?

Here is a snipped of my code:

override fun onResume() {
  super.onResume()
  launch {
    apkFiles = searchMyFiles(rootDir).await()
    showMyFiles()
  }
}

private fun searchMyFiles(dir: File): Deferred<MutableList<MyFile>> {
  return async {
    dir.walk().filter { !it.isDirectory }
      .filter { it.extension.equals(MY_EXTENSION, true) }
      .map { MyFile(it, context) }.filter { it.valid 
    }.sorted().toMutableList()
  }
}

Upvotes: 1

Views: 614

Answers (1)

Marko Topolnik
Marko Topolnik

Reputation: 200168

Although there's no evidence from your code, I'll make a guess that your default dispatcher, set in the CoroutineScope you implicitly use, is Dispatchers.Main (the UI thread). You keep using the same dispatcher for your background job instead of Dispatchers.IO.

A second point is that you use async-await for no purpose, you should use withContext instead and declare your function as suspend fun.

Given the above, your code should be

override fun onResume() {
    super.onResume()
    launch {
        apkFiles = searchMyFiles(rootDir)
        showMyFiles()
    }
}

private suspend fun searchMyFiles(dir: File) : MutableList<MyFile> = 
    withContext(Dispatchers.IO) {
        dir.walk()
           .filter { !it.isDirectory }
           .filter { it.extension.equals(MY_EXTENSION, true) }
           .map { MyFile(it, context) }
           .filter { it.valid }
           .sorted()
           .toMutableList()
    }
}

Upvotes: 5

Related Questions