6
votes

Tâche enfant annulée, parent terminée?

J'essaie de comprendre le comportement des tâches .NET lorsque les enfants sont attachés.

J'ai le code de test suivant: p>

State of parent before cancel is WaitingForChildrenToComplete
State of child before cancel is Running
A first chance exception of type 'System.OperationCanceledException' occurred in mscorlib.dll
State of parent is RanToCompletion
State of child is Canceled


2 commentaires

C'est défaut c'est l'état spécial ici où (pour une raison quelconque) de l'état des enfants se reflète dans le parent. annulé est spécifiquement appelé comme "pour se terminer dans l'état annulé, une tâche doit avoir une annulation demandée avant de commencer l'exécution, ou elle doit accuser réception d'une demande d'annulation au cours de son exécution." et aucun de ceux qui ne s'appliquent au parent.


Donc, la tâche des parents devrait attendre la tâche des enfants et lancer son propre OperationCanceledException pour son état à annuler?


3 Réponses :


4
votes

Ceci est le comportement attendu comme indiqué sur MSDN. La tâche parentale doit attendre (Faites défiler jusqu'à la section Annulation) pour la tâche de l'enfant. La tâche des parents doit gérer toutes les défauts bénins (comme l'annulation).

Pour que votre tâche parent échoue, attendez et passez le jeton: xxx

si vous utilisez Ce code pour effectuer quelque chose de productif et non seulement pour les tests, vous devez également envisager d'utiliser la tâche simplifiée.run () qui prend en charge async délégués au lieu de Task.Factory .Startnew () . Ce article est très intéressant.


11 commentaires

Où il est documenté que c'est le comportement attendu? Je ne peux pas le trouver.


Voir le lien vers MSDN J'ai ajouté dans ma réponse.


J'ai lu ce lien, je ne peux pas le trouver encore. Il vous dit que vous devez attendre que la tâche parent de gérer l'exception pas la tâche enfant comme vous dites dans votre réponse. Pouvez-vous citer le texte exact qui le signifie?


@Sriramsakthivel Il ne dit pas d'attendre pour la tâche parent, mais sur : "Il est très important d'attendre sur le parent"


Oublie ça. Peu importe. Où avez-vous lu avez-vous déjà attendre la tâche des enfants? Je ne peux pas le trouver. Il semble que Docs n'appelle pas cela.


Mon code est utilisé dans la production. Je synchronise certaines données d'un DB SQL, donc je saisie des tâches pour récupérer des données, avec Continuwith , lorsque les données sont récupérées et peuvent être analysées. Je pensais que c'était implicite que le parent annulerait si le jeton a été annulé et que le parent attendait, mais évidemment pas. Merci pour votre aide. J'ai évidemment mal compris ce que le comportement attendu était. Tout fonctionne bien maintenant.


@SriramsakThivel: C'est sous la section quand une tâche enfant annule dans l'article.


@Anutieux Même si cela fonctionne maintenant, je vous recommande vivement de passer à la tâche TASK.RUN () et d'utiliser async / attendre à la place. Voir l'article lié. Vous ne perdez rien et ne peut gagner que.


Je ne peux pas utiliser la tâche .Run () car il ajoute taskCreateOptionS.denychildattach . J'utilise async / attendre lorsque cela est possible.


Pourquoi avez-vous besoin de joindre au parent (je suis curieux)?


Eh bien, puisque j'attends maintenant manuellement manuellement que les tâches d'enfant complètent et que le wait.all retire des exceptions enfants, puis je n'ai plus besoin de joindre des enfants. L'annulation et les défauts se comportent toujours comme prévu.



1
votes

Votre exemple est assez compliqué et cache le comportement intuitif et vos attentes sont erronées.

Commençons par l'exemple de travail: xxx

pour que le parent soit Soyez annulé, vous devez appeler quelque part dans le corps du parent jeton.throwifcancellationRequée () . Cependant, il suffit d'appeler jeton.throwifcancellationRequeste estimé () ne suffira pas.

Vous devez conceptualiser comment parent et enfant Les flux d'exécution vont ensemble afin de voir pourquoi vos attentes sont erronées. xxx

Comme vous pouvez le constater dans le diagramme ci-dessus, le parent vérifie la méthode d'annulation avant que l'annulation soit demandée. L'enfant reçoit le signal d'annulation car il attend essentiellement qu'une annulation soit déclenchée. Maintenant, si vous mettez le même mécanisme dans le parent, il recevra le signal d'annulation, car il n'aurait pas fini son travail avant la signalement de l'annulation.


0 commentaires

0
votes

Quand une tâche enfant attachée annule

Le Version standard de la documentation indique que vous devez attendre la tâche mère.

Quand j'ai essayé d'attendre parenttask.wait () dans le fil principal - aucune erreur.

Le ancienne 'attendre sur la tâche des parents'.

Quand j'ai essayé d'attendre l'enfant de l'enfant.wait () dans le parentask et attendez ensuite le parenttask.wait () dans le fil principal - j'ai une erreur.

la documentation actuelle induit en erreur. D'autre part, une tâche parent devrait attendre que toutes les tâches enfants attachées par défaut. Donc, je ne comprends pas pourquoi je devrais explicitement attendre pour l'enfant. Enfant () en parenttask pour attraper TaskCanceledException dans le fil principal.


0 commentaires