简体   繁体   English

如何停止在后台定期运行的协程

[英]How to stop a coroutine running periodically in the background

I have created a coroutine extension function to run a coroutine in the background periodically at fixed interval.我创建了一个协程扩展 function 以固定的时间间隔在后台定期运行一个协程。

/**
 * 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?我已经尝试cancelAndJoin()协同程序但是我现在如何引用在后台运行的特定协同程序?

fun terminate() {
    // TODO how do I cancel the running coroutine?
}

Thanks in advance.提前致谢。

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).您的 function 确实返回了一个Job ,您所要做的就是保留该引用并取消它(除非您可以取消externalScope但我认为不会)。

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.此外,您的while不需要检查isActive - delay在内部执行此操作,因此如果它被取消,您的循环将不会达到条件检查。

As @Pawel said - you should keep reference on job you are creating.正如@Pawel 所说 - 您应该参考您正在创建的job 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()
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM