Reputation: 2281
I'm using a coroutine to format a list.
This is how it looks
val job : Job? = null
private fun formatList(originalList:MutableList<MY_OBJECT>, callback : (MutableList<MY_OBJECT>) -> Unit){
if(job != null && !job?.isCompleted!!){
job?.cancel()
}
job = viewModelScope.launch(Dispatchers.IO) {
originalList.foreach { item ->
//do something with the item.
}
}
}
This method can be called several times during runtime, and to avoid it from doing the samething, I added a cancel call if the job isn't done yet.
The problem is, in runtime, the stuffs inside the foreach block randomly produces some index related crashes.
Why is this happening? Is this something about things going behind coroutine execution? Or are there something I don't know about the foreach loop?
Upvotes: 0
Views: 185
Reputation: 1239
Making your code cancellable
For job.cancel() to work properly, you need to make your code inside coroutine cancellable.
job = viewModelScope.launch(Dispatchers.IO) {
originalList.foreach { item ->
if(!isActive) return@launch
//do something with the item.
}
if(!isActive) return@launch
// do something
}
Here the line if(!isActive) return@launch
is checking if the coroutine is still active or not. Checking for isActive
before and after computationally intensive code is good practice.
Note: if you are not doing any network or database calls, always try to use Dispatchers.Default
which is optimized for computation instead of Dispatchers.IO
.
Upvotes: 1