Sie erhalten diesen Fehler, weil die TaskKlasse die Aufgabe bereits gestartet hat, bevor sie sie Ihnen gegeben hat. Sie sollten Starteine von Ihnen erstellte Aufgabe immer nur durch Aufrufen ihres Konstruktors aufrufen, und Sie sollten dies nicht einmal tun, es sei denn, Sie haben einen zwingenden Grund, die Aufgabe beim Erstellen nicht zu starten. Wenn Sie möchten, dass es sofort gestartet wird, sollten Sie Task.Runoder verwenden Task.Factory.StartNew, um ein neues zu erstellen und zu starten Task.
Jetzt wissen wir also, dass wir diesen nervigen einfach loswerden müssen Start. Sie werden Ihren Code ausführen und feststellen, dass das Meldungsfeld sofort angezeigt wird, nicht 5 Sekunden später. Was ist damit los?
Nun, Task.Delaygibt Ihnen nur eine Aufgabe, die in 5 Sekunden erledigt sein wird. Die Ausführung des Threads wird 5 Sekunden lang nicht gestoppt. Was Sie tun möchten, ist Code, der nach Abschluss dieser Aufgabe ausgeführt wird. Dafür ContinueWithist da. Sie können Code ausführen, nachdem eine bestimmte Aufgabe erledigt wurde:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
Dies wird sich wie erwartet verhalten.
Wir könnten auch das awaitSchlüsselwort von C # 5.0 nutzen , um Fortsetzungen einfacher hinzuzufügen:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
Während eine vollständige Erklärung der Vorgänge hier den Rahmen dieser Frage sprengt, ist das Endergebnis eine Methode, die sich der vorherigen Methode sehr ähnlich verhält. 5 Sekunden nach dem Aufruf der Methode wird ein Meldungsfeld angezeigt, aber die Methode selbst wird in beiden Fällen [fast] sofort zurückgegeben. Das heißt, es awaitist sehr mächtig und ermöglicht es uns, Methoden zu schreiben, die einfach und unkompliziert erscheinen, aber es wäre viel schwieriger und unordentlicher, ContinueWithdirekt damit zu schreiben . Es vereinfacht auch den Umgang mit der Fehlerbehandlung erheblich, da viel Code auf dem Boilerplate entfernt wird.
Wait()einer Aufgabe wird der aktuelle Thread blockiert, bis die Aufgabe aufgelöst wird. Das ist fast nie das, was Sie wollen.