"Inappropiate thread-blocking method call" - too harsh

Hi,

A question regarding the inspection: Inappropiate thread-blocking method call

Note: I really value inspections to tell me what I am doing wrong, but I do not like something to be highlighted in yellow / red IF I cannot do something against it.

Sample code (within a suspend fun):

withContext(Dispatchers.IO) {
        Files.walk(inPath)
        ........
 }

Why is walk highlighted…? I am doing the best I could. Or how could I change that? I thought wrapping a IO operation in Dispatchers.IO is best practise.

Thanks for your suggestions!

It is highlighted, because suspend functions are not supposed to perform blocking IO operations that might block them for a long time. File.walk does that.

On JVM you can perform some file related IO in a non-blocking manner with AsynchronousFileChannel but as far as I know it does not support file listing. Also, it is way too complex to worth the time in most cases.

If you actually need to call it from a suspend coroutine, you could:

  1. create a channel
  2. launch a tread with File.walk
  3. in your suspend function wait for a value from the channel
  4. at the end of that thread write into the channel

I don’t know if there is a simpler solution, but if so, I also would like to know. :slight_smile:

1 Like

https://youtrack.jetbrains.com/issue/KTIJ-838

Dispatchers.IO is perfectly fine for blocking calls. Oblviously you are wasting a thread per each blocking operation performed in parallel. But it’s irrelevant in your case, since you should not run many of FS walks in parallel anyway.

Suppress the warning, and don’t bother.

3 Likes

I believe in the past IntelliJ warned if we use blocking operations, but did not warn if doing this with Dispatchers.IO. Right now it seems to always warn. I’m not sure if this change was intentional or by accident.

Hm, it is good to know that Dispatchers.IO is supposed to hide the warning.

The only thing I would like is to have: this documented somewhere in the coroutines guide. :smiley:

Dispatchers.IO is described in docs as:

The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads.

But surprisingly, I don’t see a mention about Dispatchers.IO in the guide.

Well, I had/have hard time understanding how am I supposed to use the scopes and dispatchers properly and I feel the documentation is in dire need of improvements on this particular topic.

For example, it says “do not use GlobalScope”. Ok, I understand why. So, what should I do… and here comes crazy documentation reading for 1 hour with no result. :smiley: