withTimeout und withTimeoutOrNull
Begrenzen Sie die Ausführungszeit mit Timeout-Wrappern und behandeln Sie TimeoutCancellationException.
withTimeout und withTimeoutOrNull ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum Zeitüberschreitungen?
Coroutines können bei Netzwerk- oder I/O-Vorgängen unbegrenzt hängen bleiben. withTimeout bricht den Block ab, wenn er nicht innerhalb der angegebenen Millisekunden abgeschlossen wird.
import kotlinx.coroutines.*
fun main() = runBlocking {
try {
withTimeout(200) {
delay(1000) // simulates slow network
println("This never prints")
}
} catch (e: TimeoutCancellationException) {
println("Timed out!")
}
}Grundlagen zu withTimeout
withTimeout(millis) { ... } löst TimeoutCancellationException (eine Unterklasse von CancellationException) aus, wenn der Block das Zeitlimit überschreitet.
import kotlinx.coroutines.*
suspend fun fetchData(): String {
delay(100)
return "data"
}
fun main() = runBlocking {
val result = withTimeout(500) {
fetchData()
}
println(result) // data
}withTimeoutOrNull
withTimeoutOrNull gibt bei einer Zeitüberschreitung null zurück, statt eine Ausnahme auszulösen. Dadurch lassen sich Zeitüberschreitungen leichter als normaler Ablauf behandeln.
import kotlinx.coroutines.*
fun main() = runBlocking {
val result: String? = withTimeoutOrNull(200) {
delay(1000)
"done"
}
println(result ?: "Timeout — using default")
}Zeitüberschreitung mit Rückgabewert
Beide Funktionen geben bei Erfolg den Wert des letzten Ausdrucks im Block zurück.
import kotlinx.coroutines.*
fun main() = runBlocking {
val response = withTimeoutOrNull(500) {
delay(100)
mapOf("status" to 200, "body" to "OK")
}
println(response?.get("status")) // 200
}Verschachtelte Zeitüberschreitungen
Innere Zeitüberschreitungen treten zuerst ein. Die äußere Zeitüberschreitung wird nur ausgelöst, wenn die innere nicht zuerst abbricht – nützlich für Zeitüberschreitungen pro Anfrage im Vergleich zu globalen Zeitüberschreitungen.
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 ist eine CancellationException. Daher wird sie von der Coroutine-Infrastruktur als regulärer Abbruch behandelt und nicht an den übergeordneten Scope weitergegeben.
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}")
}Ressourcenbereinigung bei Zeitüberschreitung
Verwenden Sie finally innerhalb von withTimeout, um Ressourcen auch dann freizugeben, wenn das Zeitlimit abläuft.
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")
}Wiederholen mit Zeitüberschreitung
Kombinieren Sie Zeitüberschreitungen mit einer Wiederholungslogik: Führen Sie eine Operation mit einem Zeitlimit pro Versuch aus und wiederholen Sie sie bei einem Ergebnis von null.
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 im ViewModel
Verpacken Sie in Android-ViewModels Repository-Aufrufe innerhalb von viewModelScope.launch mit withTimeoutOrNull, um bei langsamen Antworten einen Fehlerstatus anzuzeigen.
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()) }Hinweis zur Genauigkeit
withTimeout ist vom Coroutine-Dispatcher abhängig. In Tests mit TestCoroutineScheduler ist die Zeit virtuell und kann manuell vorangetrieben werden.
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")
}Die richtige Wahl treffen
Verwenden Sie withTimeout, wenn eine Zeitüberschreitung einen Fehler darstellt. Verwenden Sie withTimeoutOrNull, wenn eine Zeitüberschreitung ein erwartetes Ergebnis ist, etwa bei einem fehlenden Cache-Eintrag oder einem optionalen Prefetch.
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)
}Kurze Überprüfung
Was gibt withTimeoutOrNull zurück, wenn der Block das Zeitlimit überschreitet?
Zusammenfassung
withTimeout löst bei einer Zeitüberschreitung eine Ausnahme aus, withTimeoutOrNull gibt null zurück. Beide brechen den Block kooperativ ab und führen finally-Blöcke aus. Verwenden Sie finally zur Ressourcenbereinigung und withTimeoutOrNull, wenn eine Zeitüberschreitung ein erwartetes Ergebnis ist.
Häufig gestellte Fragen
Ist die Lektion „withTimeout und withTimeoutOrNull“ kostenlos?
Ja — der vollständige Text von „withTimeout und withTimeoutOrNull“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „withTimeout und withTimeoutOrNull“?
Begrenzen Sie die Ausführungszeit mit Timeout-Wrappern und behandeln Sie TimeoutCancellationException. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Kotlin Academy zu starten?
Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „withTimeout und withTimeoutOrNull“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?
Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Kooperative Abbruchbehandlung: isActive und ensureActive
- withTimeout und withTimeoutOrNull
- Aufräumen mit finally und NonCancellable
- Abbruchweitergabe in Coroutine-Hierarchien