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
- Cancelamento cooperativo: isActive e ensureActive
- withTimeout e withTimeoutOrNull
- Limpeza com finally e NonCancellable
- Propagação de cancelamento em hierarquias de corrotinas