Pablo
02/03/2025, 10:53 AMfun 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? ThanksSam
02/03/2025, 11:07 AMheavyTask()
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.Pablo
02/03/2025, 11:32 AMRobert Williams
02/03/2025, 12:11 PMheavyTask
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:
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 caseephemient
02/03/2025, 2:30 PMPablo
02/03/2025, 5:32 PMuli
02/11/2025, 8:59 AM