I'm on the viewmodel of my screen, and I have a fu...
# coroutines
p
I'm on the viewmodel of my screen, and I have a function on my viewmodel that it's called when user press a button. This is the function:
Copy code
fun viewModelDoHeavyTask() {
    viewModelScope.launch(Dispatchers.IO) {
        heavyTaskUseCase.heavyTask()
    }
}
As you can see, that function, called another function on my
HeavyTaskUseCase
class. The question is... should
heavyTaskUseCase.heavyTask()
be a
suspend
function? if so, why? I don't have clear when a function that is being called from inside a
corutine
should be
suspend
and which benefits I get of it. Will I notice any improvement if I do it? Thanks
s
Good question! No,
heavyTask()
should not be a suspending function. • The only benefit of adding the
suspend
modifier is that it gives you the ability to call other suspending functions. If you don't use any suspending functions, you don't need the
suspend
modifier, and you won't get any benefit from it. • Not only that, but the
suspend
modifier is a way to signal to callers that this function is main-safe, and that it'll suspend its coroutine instead of blocking its thread. If you know the function is going to do heavy CPU work or thread-blocking I/O, adding the suspend modifier would be actively misleading to callers of the function.
p
thank you, I'll wait to read more opinions. Your answer surprised me, I thought the correct whould be to mark it as a suspend function
r
Possible counter: if
heavyTask
is actually implemented as a series of smaller tasks or can be rewritten this way, making it suspend is the only way to properly support cancellation:
Copy code
suspend fun heavyTask() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
  while (coroutineContext.isActive && hasMoreSubtasks) {
    doNextSubtask()
  }
}
It also makes it trivial to do stuff like executing subtasks in parallel if that makes sense for the use case
e
if it were implemented in such a way, then it would be main-safe
👍 1
p
what you recommend ephemient?
u
No answer for a while. Maybe because we do not know enough of heavyTask’s properties. Is it io bound? Cpu bound? Can it be made to actually suspend? Is it composed of subtask that can easily be structured as @ephemient suggested? Or simply, what does it do?