import kotlinx.coroutines.*

suspend fun launchTask(delayMillis: Long) {
    println("START task $delayMillis")
    delay(delayMillis)
    println("END launchTask $delayMillis")
}

fun main() = runBlocking {
    println("start main")

    val scope = CoroutineScope(Dispatchers.Default)

    scope.launch {
        launchTask(10000)
    }
    scope.launch {
        launchTask(500)
    }

    // Cancel all coroutines in the scope after 2 seconds
    delay(2000)
    scope.cancel()

    println("end main")
}

Aqui criamos explicitamente um CoroutineScope e usá-lo para iniciar nossas duas chamadas de função suspensas, novamente usando o despachante padrão. Com o identificador do escopo, podemos iniciar nossos trabalhos e depois cancelá-los com scope.cancel(). Observe que temos duas tarefas, uma com atraso de 10.000 milissegundos. Como cancelamos após 2.000 milissegundos, obtemos a seguinte saída:


start main
START task 500
START task 10000
END launchTask 500
end main

Assim, a tarefa de 10.000 milissegundos foi iniciada, mas nunca concluída. Em vez disso, foi cancelado juntamente com o seu âmbito de aplicação.

Para outro grau de sofisticação, podemos adicionar um withTimeout bloquear: