Vous obtenez cette erreur parce que la Task
classe a déjà commencé la tâche avant de vous la donner. Vous ne devriez jamais appeler Start
une tâche que vous créez en appelant son constructeur, et vous ne devriez même pas le faire à moins d'avoir une raison impérieuse de ne pas démarrer la tâche lorsque vous la créez; si vous voulez qu'il démarre immédiatement, vous devez utiliser Task.Run
ou Task.Factory.StartNew
pour créer et démarrer un nouveau fichier Task
.
Donc, maintenant, nous savons qu'il faut simplement se débarrasser de cet embêtant Start
. Vous exécuterez votre code et découvrirez que la boîte de message s'affiche tout de suite, pas 5 secondes plus tard, qu'est-ce qui se passe avec ça?
Eh bien, Task.Delay
vous donne juste une tâche qui sera terminée en 5 secondes. Cela n'arrête pas l'exécution du thread pendant 5 secondes. Ce que vous voulez faire, c'est avoir du code qui est exécuté une fois cette tâche terminée. C'est à ça que ça ContinueWith
sert. Il vous permet d'exécuter du code une fois qu'une tâche donnée est terminée:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
Cela se comportera comme prévu.
Nous pourrions également tirer parti du await
mot - clé de C # 5.0 pour ajouter des continuations plus facilement:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
Bien qu'une explication complète de ce qui se passe ici dépasse le cadre de cette question, le résultat final est une méthode qui se comporte très similaire à la méthode précédente; il affichera une boîte de message 5 secondes après avoir appelé la méthode, mais la méthode elle-même retournera [presque] tout de suite dans les deux cas. Cela dit, await
c'est très puissant et nous permet d'écrire des méthodes qui semblent simples et directes, mais ce serait beaucoup plus difficile et plus compliqué à écrire en utilisant ContinueWith
directement. Cela simplifie également considérablement la gestion des erreurs, en supprimant beaucoup de code standard.
Wait()
sur une tâche bloquera le thread actuel jusqu'à ce que la tâche soit résolue. Ce n'est presque jamais ce que vous voulez.