2016-08-03 12 views
1

Mein Code wird weiterhin ausgeführt, bevor alle Aufgaben abgeschlossen wurden.Task.WhenAll Finishing vor Aufgaben abgeschlossen haben

Ich habe mir andere Leute mit einem ähnlichen Problem angesehen, kann aber nichts Offensichtliches sehen!

static Task MoveAccountAsync(MoverParams moverParams) 
    { 
     return Task.Run(() => 
     { 
      Console.WriteLine("Moving {0}", moverParams.Account.Name); 
      moverParams.Account.Mover.RefreshRoom(); 
      moverParams.Account.Mover.PathfindTo(moverParams.Room); 
     }); 

    } 

static async void MoveAccountsAsync(List<Account> accounts, int room) 
    { 

     List<Task> theTasks = new List<Task>(); 

     foreach (Account account in accounts) 
     { 
      // Create a new task and add it to the task list 
      theTasks.Add(MoveAccountAsync(new MoverParams(account, room))); 
     } 

     await Task.WhenAll(theTasks); 
     Console.WriteLine("Finished moving."); 
    } 

Dann einfach aus statischem Haupt Aufruf:

MoveAccountsAsync(theAccounts, room); 

Hilfe sehr geschätzt!

Cheers, Dave

+1

Sie können eine async void-Methode nicht abwarten. Es ist Feuer und Vergessen. Verwenden Sie immer "Async-Task", außer für Event-Handler. Innerhalb von 'Main()' '' .Wait() 'auf der resultierenden' Task' verwenden. –

Antwort

3

async void Methoden sind sehr entmutigt und oft (zum Beispiel hier) Zeichen für ein Problem.

Da Sie nicht erwarten, Ihre Methode Anruf (und Sie können nicht await es, weil es void zurückgibt) Caller wird nicht warten, bis die ganze Arbeit zu Ende, bevor Sie mit der nächsten Anweisung weitermachen.

Ändern Sie Ihre Methode, Task und await es zurückzukehren, um das Problem zu beheben. Wenn Sie aus dem synchronen Kontext (z. B. Main Methode) in MoveAccountsAsync aufrufen, verwenden Sie Wait, um auf die Ergebnisse zu warten. Beachten Sie jedoch, dass unter bestimmten Bedingungen (z. B. bei der Ausführung als ASP.NET-Anwendung) Deadlocks auftreten können.

+0

Also muss ich eine andere Aufgabe erstellen, die die untergeordneten Aufgaben hervorbringt? Warten Sie dann, bis die Hauptaufgabe abgeschlossen ist, anstatt auf die untergeordneten Aufgaben zu warten. Entschuldigung, das ist das erste Mal, dass ich mit Threads arbeite! – DavidC799

+0

'Aufgabe'! = Thema. Eine Aufgabe, auf die Sie warten, bedeutet nicht, dass dort ein neuer Thread ist. Nur dass es etwas Arbeit gibt, die passiert und du wartest darauf, dass es endet. – MarcinJuraszek

+0

Hoppla! Ist das, was ich gesagt habe, richtig? Ich habe versucht: 'Task.Run (() => MoveAccountsAsync (theAccounts, room)). Wait();' beim Aufruf, aber mit den gleichen Ergebnissen wie zuvor ... – DavidC799