Task et ValueTask sont deux façons de représenter une opération asynchrone qui peut se compléter dans le futur, mais elles ont des différences importantes de performance et d’usage. Voyons ça en détail.
1. Task
-
Type référence (
class) qui représente une opération asynchrone. -
Toujours alloué sur le heap.
-
Peut être awaité avec
await. -
Facile à utiliser et très courant.
-
Supporte la composition, comme
Task.WhenAlletTask.WhenAny.
Exemple :
Points clés :
-
Allocation sur le heap → un peu plus lourd si beaucoup de petites tâches rapides.
-
Toujours sûr pour les opérations qui doivent être awaitées plusieurs fois.
2. ValueTask
-
Type struct (valeur type) → peut éviter des allocations sur le heap pour des tâches très rapides ou souvent synchrones.
-
Peut être awaité comme un
Task. -
Recommandé quand la tâche peut se terminer immédiatement ou retourner un résultat déjà disponible.
-
Attention : si vous attendez plusieurs fois le même
ValueTask, vous devez le convertir en Task (AsTask()), sinon comportement indéfini.
Exemple :
Points clés :
-
Réduit les allocations heap pour les opérations rapides.
-
Moins flexible que
Tasksi vous devez réutiliser ou combiner la tâche. -
Ne pas utiliser pour des tâches longues ou partagées à plusieurs endroits.
3. Comparaison rapide
| Caractéristique | Task | ValueTask |
|---|---|---|
| Type | Reference type (class) | Value type (struct) |
| Allocation heap | Oui | Non si résultat immédiat |
| Réutilisable | Oui | Non, il ne doit pas être awaité plusieurs fois |
| Usage recommandé | Toutes opérations asynchrones | Opérations très rapides ou souvent synchrones |
Composition (WhenAll, etc.) | Facile | Moins pratique, doit convertir en Task |
✅ Règle pratique
-
Task → sûr, simple, standard pour la plupart des cas.
-
ValueTask → optimisation pour micro-performances, surtout si beaucoup de tâches se terminent immédiatement.
Aucun commentaire:
Enregistrer un commentaire