Home > Enterprise >  How to stop a coroutine running periodically in the background
How to stop a coroutine running periodically in the background

Time:12-31

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()
   }
}
  • Related