250 votes

Quelle est la différence entre Task.Run() et Task.Factory.StartNew()

J’ai la méthode :

Et je veux commencer cette méthode dans une nouvelle tâche. Je peux commencer la nouvelle tâche comme ça

ou ce

Mais y a-t-il une différence entre et . Deux d'entre eux sont à l’aide de ThreadPool et commencent Method() immédiatement après avoir créé l’instance de la tâche. Quand nous devrions utiliser la première version et quand le deuxième ?

247voto

Christos Points 11296

La deuxième méthode, Task.Run, a été présenté dans une version ultérieure de la .NET framework (.NET 4.5).

Cependant, la première méthode, Task.Factory.StartNew, vous donne la possibilité de définir beaucoup de choses utiles sur le fil que vous souhaitez créer, tout en Task.Run ne fournit pas cette.

Par exemple, disons que vous voulez créer une tâche en cours d'exécution du thread. Si un thread du pool de thread va être utilisé pour cette tâche, alors que cela pourrait être considéré comme un abus du pool de threads.

Une chose que vous pourriez faire pour éviter ce serait la tâche doit être exécutée dans un thread séparé. Un nouveau thread qui serait dédiée à cette tâche et qui sera détruite une fois votre tâche aurait été terminé. Vous ne peut pas réaliser cela avec l' Task.Run, tandis que vous pouvez le faire avec l' Task.Factory.StartNew, comme ci-dessous:

Task.Factory.StartNew(..., TaskCreationOptions.LongRunning);

Comme il est dit ici:

Ainsi, dans l' .NET Framework 4.5 Developer Preview, nous avons présenté le nouvelle Tâche.Méthode Run. Ce qui ne obsoletesde la Tâche.Usine.StartNew, mais plutôt devrait tout simplement être considéré comme un moyen rapide d'utilisation De la tâche.Usine.StartNew sans avoir besoin de spécifier un tas de les paramètres. C'est un raccourci. En fait, la Tâche.Run est en fait mis en œuvre en termes de la même logique utilisée pour la Tâche.Usine.StartNew, juste en passant des paramètres par défaut. Lorsque vous passez d'une Action De la tâche.Exécuter:

Task.Run(someAction);

c'est exactement équivalent à:

Task.Factory.StartNew(someAction, 
    CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

34voto

Scott Chamberlain Points 32782

Voir cet article de blog qui décrit la différence. Faisant essentiellement :

Est identique à cela :

32voto

user3185569 Points 22924

L' Task.Run était introduit dans les plus récents .NET framework version et il est recommandé.

En commençant par la .NET Framework 4.5, la Tâche.La méthode est la recommandé pour le lancement d'un calcul lié à la tâche. Utiliser le StartNew méthode uniquement lorsque vous avez besoin d'un contrôle précis pour une longue durée, liée au calcul de la tâche.

L' Task.Factory.StartNew a plus d'options, l' Task.Run est un raccourci:

La méthode Run fournit un ensemble de surcharges qui font qu'il est facile de commencer une tâche à l'aide de valeurs par défaut. C'est une alternative légère à la StartNew les surcharges.

Et par abréviation, je veux dire une technique de raccourci:

public static Task Run(Action action)
{
    return Task.InternalStartNew(null, action, null, default(CancellationToken), TaskScheduler.Default,
        TaskCreationOptions.DenyChildAttach, InternalTaskOptions.None, ref stackMark);
}

24voto

Roger Points 499

Selon ce post par Stephen Cleary, la Tâche.Usine.StartNew() est dangereux:

Je vois beaucoup de code sur les blogs et dans les questions que l'utilisation de la Tâche.Usine.StartNew de rotation de travailler sur un thread d'arrière-plan. Stephen Toub a un excellent article de blog qui explique pourquoi la Tâche.Run est mieux que sur la Tâche.Usine.StartNew, mais je pense que beaucoup de gens n'ont tout simplement pas lire (ou de ne pas le comprendre). Donc, j'ai pris les mêmes arguments, a ajouté un peu plus énergique de la langue, et nous allons voir comment cela va. :) StartNew offre beaucoup plus d'options que sur la Tâche.Exécuter, mais il est très dangereux, comme nous allons le voir. Vous devriez préférer la Tâche.Exécuter plus de Tâches.Usine.StartNew dans async code.

Voici les vraies raisons:

  1. Ne pas comprendre async délégués. C'est en fait la même que le point 1 les raisons pour lesquelles vous souhaitez utiliser StartNew. Le problème c'est que lorsque vous passez un async délégué à StartNew, il est naturel de supposons que le retour de l'tâche représente que délégué. Cependant, depuis StartNew ne comprends pas async délégués, ce qui fait tâche représente n'est que le début de ce délégué. C'est l'un des d'abord les pièges que les codeurs de rencontrer lors de l'utilisation de StartNew en asynchrone code.
  2. Déroutant par défaut planificateur. OK, le truc question de temps: dans la le code ci-dessous, ce thread n'a la méthode "A" à courir?
Task.Factory.StartNew(A);

private static void A() { }

Eh bien, vous savez que c'est une question piège, hein? Si vous avez répondu "un fil de pool de threads", je suis désolé, mais ce n'est pas correct. "Un" se lancer sur quelle que soit TaskScheduler est actuellement en cours d'exécution!

Donc, cela signifie qu'il risque de les exécuter sur le thread de l'INTERFACE utilisateur si une opération est terminée et il commissaires de retour vers le thread d'INTERFACE utilisateur en raison d'une poursuite de Stephen Cleary explique dans son post.

Dans mon cas, j'ai essayé d'exécuter des tâches en arrière-plan lors du chargement d'un datagrid pour une vue tout en affichant un occupé de l'animation. Le occupé de l'animation ne s'affiche pas lors de l'utilisation d' Task.Factory.StartNew() mais l'animation s'affiche pas correctement lorsque je suis passé à l' Task.Run().

Pour plus de détails, veuillez voir https://blog.stephencleary.com/2013/08/startnew-is-dangerous.html

-10voto

Devendra Rusia Points 11

Dans mon application qui appelle deux services, j’ai comparé les deux Task.Run et Task.Factory.StartNew. J’ai trouvé que dans mon cas, deux d'entre eux fonctionnent très bien. Toutefois, le second est plus rapide.

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