I have created a coroutine extension function to run a coroutine in the background periodically at fixed interval.
/**
* This method will receive a coroutine function block and will handle it according to the provided parameters.
*/
fun CoroutineScope.runWithCoroutineHandler(
intervalMils: Long,
startDelayMils: Long = 0L,
maxDurationMils: Long = 0L,
suspendFunctionBlock: suspend () -> Unit
): Job = launch(this.coroutineContext) {
delay(startDelayMils)
val startTime = System.nanoTime()
do {
suspendFunctionBlock()
delay(intervalMils)
} while ((maxDurationMils == 0L && isActive) || (isActive && ((System.nanoTime() - startTime) / 1000000 < maxDurationMils)))
}
Now, I run a coroutine as following in a repository:
fun initialize() {
externalScope.runWithCoroutineHandler(intervalMils = INTERVAL_MILLIS) {
process()
}
}
The issue now is, how do i correctly stop this coroutine from the background on demand?
I have tried to cancelAndJoin()
the coroutine but how can I now refer to the specific coroutine that is running in the background?
fun terminate() {
// TODO how do I cancel the running coroutine?
}
Thanks in advance.
CodePudding user response:
Your function does return a Job
, all you have to do is keep that reference and cancel it (unless you're fine with cancelling externalScope
but I assume not).
Also your while
does not need to check isActive
- delay
does so internally so your loop won't reach condition check if it gets cancelled.
CodePudding user response:
As @Pawel said - you should keep reference on job
you are creating.
Simplest:
class MyExecutor(private val externalScope: CoroutineScope){
private var job: Job? = null
fun initialize() {
job = externalScope.runWithCoroutineHandler(intervalMils = INTERVAL_MILLIS) {
process()
}
}
fun terminate() {
job?.cancelAndJoin()
}
}