Task.Delay est-il vraiment asynchrone comme une opération d'E / S, c'est-à-dire repose-t-il sur du matériel et des interruptions au lieu d'un thread?
J'ai trouvé une tonne de contenus connexes qui tournent tous autour du pot et je n'ai jamais été en mesure de trouver une réponse. Je suis presque sûr à 100% qu'il Task.Delay(int)
n'utilise pas de thread, car je peux exécuter ce code sur ma machine avec seulement 16 processeurs logiques:
var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);
Et cela prend dix secondes pour terminer. S'il utilisait environ cent mille fils, cela prendrait un peu plus de temps, je pense.
Donc ma question est comment ça Task.Delay(int)
marche? Pas de la manière que cette question SO mal intitulée indique, mais du point de vue des threads et des ressources matérielles.
Réponses
Dans l'implémentation actuelle de .NET, il existe un seul «thread de minuterie» qui effectue simplement le suivi des instances de minuteur gérées et déclenche leurs événements aux moments appropriés. Ce thread de minuterie se bloquera sur son signal de commande avec un délai d'expiration défini sur l'heure d'échéance du minuteur suivant. Le signal de commande est utilisé pour ajouter / supprimer / modifier des minuteries, donc lorsque cette demande de blocage expire, le thread du minuteur sait que le minuteur suivant s'est déclenché. Il s'agit d'une opération de blocage de thread normal, donc en interne, le thread est inactif et supprimé de la file d'attente du planificateur jusqu'à ce que l'opération de blocage se termine ou expire. Le délai d'expiration de ces opérations est géré par l'interruption du temporisateur du planificateur du système d'exploitation.
Donc, techniquement, il y a un thread, mais ce n'est qu'un thread par processus, pas un thread par Task.Delay
.
J'insiste à nouveau sur le fait que c'est dans l' implémentation actuelle de .NET. D'autres solutions ont été proposées, comme un thread de temporisation par CPU, ou un pool dynamique de threads de temporisation. Peut-être ont-ils été expérimentés et rejetés pour une raison quelconque, ou peut-être qu'une solution alternative sera adoptée à l'avenir. AFAIK ceci n'est officiellement documenté nulle part, il s'agit donc d'un détail de mise en œuvre.