Отмена в Kotlin
Долгая фоновая задача не обязана идти до конца.
У Job есть cancel: он помечает
корутину отмененной. Внутри цикла с паузами
смотрят isActive и выходят, когда флаг
стал ложным.
Типичный шаблон - счетчик тиков с delay
между итерациями и проверкой активности:
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val ticker = launch {
var n = 0
while (isActive) {
println(n)
n++
delay(50)
}
}
delay(120)
ticker.cancel()
ticker.join()
println("stopped")
}
}
После cancel очередная проверка
isActive завершит цикл. Функция join
гарантирует, что "stopped" напечатается
уже после выхода из лямбды.
Отмену можно вызвать сразу после старта, если работа еще не успела напечатать все значения:
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val spinner = launch {
while (isActive) {
println("spin")
delay(100)
}
}
spinner.cancel()
spinner.join()
println("idle")
}
}
Фоновая корутина в цикле выводит "beep"
с паузой между строками. Через короткое ожидание
отмените её и дождитесь завершения. Затем
напечатайте "quiet".
Запустите задачу, которая увеличивает счетчик
и печатает его, пока активна. Отмените дескриптор
после нескольких тиков и выведите "halt"
после join.