web-dev-qa-db-fra.com

Kotlin: Périmètre Coroutines vs contexte Coroutine

Quelqu'un peut-il expliquer la différence entre eux? Je pense que la portée fournit une référence (par exemple, Job) pour les annuler et le contexte fournit une référence au thread sous-jacent. Est-ce vrai?

14
Jose

Portée

Chaque générateur de coroutine (comme le lancement, l'async, etc.) et chaque fonction de portée (comme coroutineScope, withContext, etc.) fournit sa propre portée avec sa propre instance de Job dans le bloc interne de code qu'il exécute. Par convention, ils attendent tous que toutes les coroutines de leur bloc soient terminées avant de s'achever, renforçant ainsi la discipline de la concurrence structurée.

Source

Contexte

Les coroutines s'exécutent toujours dans un contexte qui est représenté par la valeur du type CoroutineContext, définie dans la bibliothèque standard de Kotlin.

Le contexte coroutine est un ensemble de divers éléments. Les principaux éléments sont le travail de la coroutine, que nous avons vu auparavant, et son répartiteur, qui est couvert dans cette section.

Source

1
Willi Mentzel

Oui, en principe vous avez raison, voici plus de détails.

Portée

  • une coroutine doit s'exécuter dans une portée
  • c'est un moyen de garder une trace de toutes les coroutines qui y courent
  • toutes les ( coopératives ) coroutines peuvent être annulées via leur portée
  • les étendues obtiennent des exceptions non capturées
  • ils sont un moyen de lier les coroutines à un cycle de vie spécifique à une application (par exemple viewModelScope dans Android) pour éviter les fuites

Contexte

Le contexte détermine sur quel thread les coroutines s'exécuteront. Il y a quatre options:

  • Dispatchers.Default - pour un travail intense sur le processeur (par exemple, trier une grande liste)
  • Dispatchers.Main - ce que ce sera dépend de ce que vous avez ajouté aux dépendances d'exécution de vos programmes (par exemple kotlinx-coroutines-Android , pour le fil d'interface utilisateur dans Android)
  • Dispatchers.Unconfined - exécute les coroutines non confinées sur aucun thread spécifique
  • Dispatchers.IO - pour les gros travaux IO (par exemple, requêtes de base de données de longue durée)

L'exemple suivant rassemble à la fois la portée et le contexte. Il crée une nouvelle étendue dans laquelle les coroutines s'exécuteront (si elles ne sont pas modifiées) sur un thread désigné pour le travail IO) et les annule via leur étendue.

val scope = CoroutineScope(context = Dispatchers.IO) 
val job = scope.launch {
    val result = suspendFunc1()
    suspendFunc2(result)
}
// ...
scope.cancel() // suspendFunc1() and suspendFunc2() will be cancelled
1
Willi Mentzel