133 votes

Est il acceptable de ne pas appeler Dispose() sur un objet Task TPL ?

Je veux déclencher l'exécution d'une tâche sur un thread d'arrière-plan. Je ne veux pas attendre l'achèvement des tâches.

Dans .net 3.5, j'aurais fait ceci:

ThreadPool.QueueUserWorkItem(d => { DoSomething(); });

Dans .net 4 le TPL est la manière suggérée. Le modèle courant, j'ai vu recommandée est de:

Task.Factory.StartNew(() => { DoSomething(); });

Cependant, l' StartNew() méthode retourne un Task objet qui implémente IDisposable. Cette semble être négligé par les personnes qui recommandent ce modèle. La documentation MSDN sur l' Task.Dispose() méthode dit:

"Toujours faire appel à Éliminer avant de vous libérer de votre dernière référence à la Tâche."

Vous ne pouvez pas appeler disposer sur une tâche à la fois, afin d'avoir le thread principal d'attente et appeler dispose irait à l'encontre de la point de le faire sur un thread d'arrière-plan dans la première place. Il également n'a pas l'air d'être fini événement qui peut être utilisé pour le nettoyage.

La page MSDN sur la Tâche de la classe n'a pas de commentaire sur ce, et le livre "Pro C#2010...", recommande le même modèle et ne fait aucun commentaire sur la tâche de l'élimination.

Je sais que si je laisse le finaliseur l'attraper à la fin, mais est-ce que ça va revenir et de me mordre quand je suis en train de faire beaucoup de fire & forget tâches de ce genre et le finaliseur fil est dépassé?

Donc mes questions sont:

  • Est-il acceptable de ne pas appeler Dispose() sur le Task de la classe dans ce cas? Et si oui, pourquoi et il y a des risques/conséquences?
  • Est-il de la documentation sur ce sujet?
  • Ou est-il un moyen approprié pour l'élimination de la Task objet que j'ai manqué?
  • Ou est-il une autre façon de faire le feu et oublier les tâches avec le TPL?

117voto

Kirill Muzykov Points 1719

Il y a une discussion à ce propos dans les forums MSDN.

Stephen Toub, un membre de la Microsoft pfx équipe a ceci à dire:

De la tâche.Disposer existe en raison de la Tâche potentiellement l'enchaînement d'un événement de la poignée utilisé lors de l'attente sur la tâche à complète, dans le cas de l'attente thread en fait, pour le bloquer (comme contrairement à la filature ou potentiellement l'exécution de la tâche qu'il est en attente). Si tout ce que vous faites est à l'aide de les continuations, cet événement poignée ne jamais être alloué
...
il est probablement préférable de s'appuyer sur la finalisation de prendre soin des choses.

Mise À Jour (Octobre 2012)
Stephen Toub a posté un blog intitulé Dois-je disposer de Tâches? ce qui donne un peu plus de détail, et explique les améliorations .Net 4.5.

En résumé: Vous n'avez pas besoin de disposer d' Task objets 99% du temps. Comme de .Net 4.5, un Task alloue l'interne attendre la poignée est lorsque vous utilisez explicitement l' IAsyncResult.AsyncWaitHandle de la Task.

13voto

Hans Passant Points 475940

C'est le même type de problème qu'avec la classe Thread. Il consomme 5 système d'exploitation gère mais ne pas mettre en œuvre IDisposable. Bonne décision de les concepteurs d'origine, il y a bien sûr quelques-uns des moyens raisonnables pour appeler la méthode dispose (). Vous devez appeler Join() en premier.

La Tâche de la classe ajoute une poignée à ce, un manuel interne événement de réinitialisation. Qui est le moins cher des ressources de système d'exploitation, il est. Bien sûr, sa méthode dispose() ne peut libérer que d'une poignée d'événement, pas le 5 poignées de Fil en consomme. Oui, ne vous embêtez pas.

Faites attention, vous devriez être intéressé par la tâche de IsFaulted de la propriété. C'est un assez laid sujet, vous pouvez lire plus à ce sujet dans cet article de la Bibliothèque MSDN. Une fois que vous infligez avec cela, vous devriez également avoir une bonne place dans votre code pour éliminer les tâches.

-1voto

Chris Marisic Points 11495

J’aimerais voir quelqu'un pèsent sur la technique décrite dans ce post : appel de délégué asynchrone tire et oublie de type sécurisé en c#

Il ressemble à une méthode d’extension simple va gérer tout triviales cas d’interagir avec les tâches et être en mesure d’appeler dispose à ce sujet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X