Est prevTask.Wait() recommandé pour être utilisé avec ContinueWith (à partir des Tâches de la bibliothèque)?
Donc on m'a dit récemment que la façon dont j'ai été en utilisant mon .ContinueWith pour des Tâches n'était pas la bonne façon de les utiliser. Je n'ai pas encore trouver la preuve de cette sur internet, donc je vais vous demander de vous les gars et voir quelle est la réponse. Voici un exemple de la façon dont j'utilise .ContinueWith:
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 3");
});
}
Maintenant, je sais que c'est un simple exemple et il va courir très vite, mais il suffit de supposer chaque tâche fait un peu plus de temps de fonctionnement. Donc, ce qu'on m'a dit que dans le .ContinueWith, vous avez besoin de dire prevTask.Wait(); sinon, vous pourriez vous faire le travail avant que la précédente tâche est terminée. Est-il même possible? J'ai pris mon deuxième & troisième tâche ne fonctionnera qu'une fois leur tâche précédente se termine.
Ce que m'a dit comment écrire le code:
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 3");
});
}
- N'utilisez pas de StartNew blog.stephencleary.com/2013/08/startnew-is-dangerous.html
Vous devez vous connecter pour publier un commentaire.
Ehhh.... Je pense que certaines réponses sont manque quelque chose: qu'advient-il des exceptions?
La seule raison que vous appelez
Wait
dans une suite serait d'observer un potentiel exception de l'antécédent dans la poursuite elle-même. La même observation pourrait se produire si vous avez accédé àResult
dans le cas d'unTask<T>
et aussi si vous avez manuellement consulté leException
de la propriété.Franchement, je ne dirais pas
Wait
ou l'accèsResult
parce que si il ya une exception, vous aurez à payer le prix de relancer à nouveau, ce qui est une surcharge inutile. Au lieu de cela, vous pouvez simplement vérifier laIsFaulted
bien de l'antécédentTask
. Sinon, vous pouvez créer fourche flux de travail en enchaînant sur plusieurs sœur suites que seul le feu basé sur le succès ou l'échec avecTaskContinuationOptions.OnlyOnRanToCompletion
etTaskContinuationOptions.OnlyOnFaulted
.Maintenant, il n'est pas nécessaire d'observer l'exception de l'antécédent dans la suite, mais vous ne souhaitez pas que votre flux de travail pour aller de l'avant si, par exemple, "l'Étape 1" a échoué. Dans ce cas: spécification
TaskContinuationOptions.NotOnFaulted
à votreContinueWith
appels empêcher la continuation logique de jamais le même tir.Gardez à l'esprit que, si votre propre suites de ne pas observer l'exception, la personne qui est en attente sur l'ensemble de ce flux de travail pour compléter va être le seul à l'observer. Soit ils sont
Wait
ing sur leTask
en amont ou ont ajouté leur propre poursuite de savoir quand il est complet. Si c'est le dernier cas, la poursuite aurait besoin d'utiliser celui-ci d'observation de la logique.TaskContinuationOptions
Que vous l'utilisez correctement.
Source: De la tâche.ContinueWith Méthode (Action comme MSDN)
Avoir à appeler
prevTask.Wait()
dans tous lesTask.ContinueWith
invocation semble être une drôle de façon de répétition inutile de la logique - c'est à dire de faire quelque chose pour être "super duper sûr" parce que vous ne comprenez pas qu'un certain morceau de code ne. Comme la vérification pour une valeur nulle, juste pour jeter unArgumentNullException
où il aurait été jeté de toute façon.Alors, non, celui qui vous a dit que c'est faux et ne correspond probablement pas à comprendre pourquoi
Task.ContinueWith
existe.Qui vous a dit cela?
Citant MSDN:
Aussi, quel serait le but de Continuer si elle n'était pas d'attente pour la précédente tâche à effectuer?
Vous pouvez même tester par vous-même:
De la MSDN sur
Task.Continuewith
Je pense que la façon dont vous vous attendez à ce qu'il fonctionne dans le premier exemple est la manière correcte.
Vous pourriez aussi envisager d'utiliser la Tâche.Exécuter à la place de la Tâche.Usine.StartNew.
Stephen Cleary est post de blog et le Stephen Toub du poste qu'il a des références expliquer les différences. Il y a aussi une discussion dans cette réponse.
En Accédant à
Task.Result
vous êtes en train de faire la même logique pourtask.wait
Je vais répéter ce que beaucoup ont déjà parlé,
prevTask.Wait()
est inutile.Pour plus d'exemples, on peut aller à Enchaînant des Tâches à l'aide de la Poursuite des Tâches, encore un autre lien par Microsoft avec de bons exemples.