Après avoir traité le modèle asynchrone / attente de C # pendant un certain temps maintenant, je me suis soudain rendu compte que je ne savais pas vraiment comment expliquer ce qui se passait dans le code suivant:
async void MyThread()
{
while (!_quit)
{
await GetWorkAsync();
}
}
GetWorkAsync()
est supposé renvoyer un fichier attendu Task
qui peut ou non provoquer un changement de thread lorsque la continuation est exécutée.
Je ne serais pas confus si l'attente n'était pas dans une boucle. Je m'attendrais naturellement à ce que le reste de la méthode (c'est-à-dire la poursuite) s'exécute potentiellement sur un autre thread, ce qui est bien.
Cependant, à l'intérieur d'une boucle, le concept de «le reste de la méthode» me brouille un peu.
Qu'arrive-t-il au "reste de la boucle" si le thread est activé en continuation ou s'il n'est pas activé? Sur quel thread la prochaine itération de la boucle est-elle exécutée?
Mes observations montrent (non vérifiées de façon concluante) que chaque itération commence sur le même thread (l'original) tandis que la suite s'exécute sur un autre. Est-ce vraiment possible? Si oui, s'agit-il alors d'un degré de parallélisme inattendu qui doit être pris en compte vis-à-vis de la sécurité des threads de la méthode GetWorkAsync?
MISE À JOUR: Ma question n'est pas un doublon, comme suggéré par certains. Le while (!_quit) { ... }
modèle de code n'est qu'une simplification de mon code actuel. En réalité, mon thread est une boucle longue durée qui traite sa file d'attente d'entrée d'éléments de travail à intervalles réguliers (toutes les 5 secondes par défaut). La vérification de la condition de sortie réelle n'est pas non plus une simple vérification de champ comme le suggère l'exemple de code, mais plutôt une vérification de la gestion des événements.