0Pricing
Kotlin Academy · Aula

withTimeout e withTimeoutOrNull

Limite o tempo de execução com wrappers de tempo limite e trate TimeoutCancellationException.

withTimeout e withTimeoutOrNull é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

Por que usar tempos limite

As corrotinas podem ficar suspensas indefinidamente em operações de rede ou E/S. withTimeout cancela o bloco se ele não for concluído dentro do número de milissegundos informado.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        withTimeout(200) {
            delay(1000)  // simulates slow network
            println("This never prints")
        }
    } catch (e: TimeoutCancellationException) {
        println("Timed out!")
    }
}

Noções básicas de withTimeout

withTimeout(millis) { ... } lança TimeoutCancellationException (uma subclasse de CancellationException) se o bloco exceder o limite.

import kotlinx.coroutines.*
suspend fun fetchData(): String {
    delay(100)
    return "data"
}
fun main() = runBlocking {
    val result = withTimeout(500) {
        fetchData()
    }
    println(result) // data
}

withTimeoutOrNull

withTimeoutOrNull retorna null quando o tempo limite é atingido, em vez de lançar uma exceção, facilitando o tratamento de tempos limite como parte do fluxo normal.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val result: String? = withTimeoutOrNull(200) {
        delay(1000)
        "done"
    }
    println(result ?: "Timeout — using default")
}

Tempo limite com valor de retorno

Ambas as funções retornam o valor da última expressão do bloco em caso de sucesso.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val response = withTimeoutOrNull(500) {
        delay(100)
        mapOf("status" to 200, "body" to "OK")
    }
    println(response?.get("status")) // 200
}

Aninhamento de tempos limite

Os tempos limite internos expiram primeiro. O tempo limite externo só é acionado se o interno não cancelar primeiro — isso é útil para diferenciar tempos limite por solicitação de tempos limite globais.

import kotlinx.coroutines.*
fun main() = runBlocking {
    withTimeoutOrNull(1000) {       // global
        withTimeoutOrNull(200) {    // per-call
            delay(300)
            println("inner done")  // won't print
        } ?: println("Inner timed out")
        delay(100)
        println("outer still running")
    }
}

TimeoutCancellationException

TimeoutCancellationException é uma CancellationException, portanto é tratada como um cancelamento normal pelo mecanismo de corrotinas e não se propaga para o escopo pai.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            withTimeout(100) { delay(1000) }
        } catch (e: TimeoutCancellationException) {
            println("Caught in child: ${e.message}")
        }
    }
    job.join()
    println("Parent still running: ${isActive}")
}

Limpeza de recursos ao atingir o tempo limite

Use finally dentro de withTimeout para liberar recursos mesmo quando o tempo se esgotar.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val result = withTimeoutOrNull(150) {
        try {
            println("Opening resource")
            delay(300)
            "result"
        } finally {
            println("Closing resource") // always runs
        }
    }
    println("Result: $result")
}

Nova tentativa com tempo limite

Combine o tempo limite com a lógica de novas tentativas: tente realizar uma operação com um tempo limite por tentativa e repita em caso de resultado nulo.

import kotlinx.coroutines.*
suspend fun tryFetch(attempt: Int): String? = withTimeoutOrNull(200) {
    delay(if (attempt < 3) 300L else 100L) // fails first 2 attempts
    "success on attempt $attempt"
}
fun main() = runBlocking {
    var result: String? = null
    var attempt = 1
    while (result == null) {
        result = tryFetch(attempt++)
    }
    println(result)
}

withTimeout em ViewModel

Nos ViewModels do Android, envolva as chamadas ao repositório com withTimeoutOrNull em viewModelScope.launch para mostrar o estado de erro quando as respostas demorarem.

import kotlinx.coroutines.*
// Pseudocode pattern:
suspend fun loadUser(): String = withTimeoutOrNull(3000) {
    // repo.getUser()
    delay(100)
    "Alice"
} ?: "Timeout — using cached data"
fun main() = runBlocking { println(loadUser()) }

Observação sobre precisão

withTimeout depende do despachante de corrotinas. Em testes que usam TestCoroutineScheduler, o tempo é virtual e pode ser avançado manualmente.

import kotlinx.coroutines.*
// In unit tests with runTest:
// runTest {
//     withTimeout(1000) {
//         delay(999)  // virtual time — completes instantly
//         println("done")
//     }
// }
fun main() = runBlocking {
    println("Use runTest for virtual-time timeout testing")
}

Escolhendo entre os dois

Use withTimeout quando o tempo limite representar um erro. Use withTimeoutOrNull quando o tempo limite for um resultado esperado (por exemplo, ausência no cache ou pré-carregamento opcional).

import kotlinx.coroutines.*
fun main() = runBlocking {
    // Mandatory: throw on timeout
    // withTimeout(500) { criticalOp() }

    // Optional: null on timeout
    val cached = withTimeoutOrNull(50) {
        delay(200); "fresh"
    } ?: "stale"
    println(cached)
}

Verificação rápida

O que withTimeoutOrNull retorna quando o bloco excede o limite de tempo?

Recapitulação

withTimeout lança uma exceção quando o tempo limite é atingido; withTimeoutOrNull retorna nulo. Ambas cancelam o bloco de forma cooperativa e executam os blocos finally. Use finally para a limpeza de recursos e withTimeoutOrNull quando o tempo limite for um resultado esperado.

Perguntas Frequentes

A aula “withTimeout e withTimeoutOrNull” é grátis?

Sim — o texto completo de “withTimeout e withTimeoutOrNull” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “withTimeout e withTimeoutOrNull”?

Limite o tempo de execução com wrappers de tempo limite e trate TimeoutCancellationException. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “withTimeout e withTimeoutOrNull”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Cancelamento cooperativo: isActive e ensureActive
  2. withTimeout e withTimeoutOrNull
  3. Limpeza com finally e NonCancellable
  4. Propagação de cancelamento em hierarquias de corrotinas
← Voltar para Kotlin Academy