Cancelled job still running after cancelAndJoin()

122 Views Asked by At

I have an Android screen update job that gets called whenever the slider is moved. Before calling it again I call cancelAndJoin(). Still, sometimes there is more than one instance of the update running at the same time, causing problems.

So my code looks like this:

CoroutineScope(Dispatchers.Default).launch{

updateJob.cancelAndJoin()

updateJob=launch {long update....}

}

Any help on how to absolutely make sure that there is no single instance of update running before calling it again?

1

There are 1 best solutions below

0
votopec On

What I have managed to do is to check if Job is in transient cancelling state before even calling cancelAndJoin(). Looks like it can arrive in this state: isCompleted:false isCancelled:true isActive:false. Then somehow it still runs even though it gets cancelAndJoin()

In case it is, I just delay till it is not.

 while(updateJob.isCancelled && !updateJob.isCompleted && !updateJob.isActive){
                delay(10)
                //old canceled job is still finishing. Wait till it finishes               
            }
updateJob.cancelAndJoin()
updateJob=launch{ ...}

Am I doing the right thing? Seems to be fixing the error. I have logged the times that delay gets called and it happens a few times on slower devices, so it fixes the problem.

EDIT:

The answer from @broot is the solution. There should be no CoroutineContext(Dispatchers.Default).launch{...}. Once in there, the old job still runs in parallel when cancelled till it hits the suspend function. Without it it finishes first before starting again.