2013-07-12 25 views
13

staram się zrobić coś takiego:Czekają na liście zadań

foreach (var o in ObjectList) 
{ 
    CalculateIfNeedToMakeTaskForO(o); 

    if (yes) 
     TaskList.Add(OTaskAsync()); 
} 

Teraz chciałbym czekać na wszystkich tych zadań do wykonania. Poza tym robi

foreach(var o in ObjectList) 
{ 
    Result.Add("result for O is: "+await OTaskAsync()); 
} 

Czy jest coś mogę zrobić? (Lepsze, bardziej elegancki, bardziej "poprawne")

Odpowiedz

21

Szukasz Task.WaitAll (zakładając, że TaskList realizowane IEnumerable<Task>)

Task.WaitAll(TaskList.ToArray()); 

EDIT: Od WaitAll zajmuje tylko tablicę zadania (lub listę z Task w postaci zmiennej tablicy argumentów), musisz przekonwertować swoją Enumerable. Jeśli chcesz metodę rozszerzenia, można zrobić coś takiego:

pulic static void WaitAll(this IEnumerable<Task> tasks) 
{ 
    Task.WaitAll(tasks.ToArray()); 
} 

TaskList.WaitAll(); 

Ale to naprawdę tylko cukier syntaktyczny.

+0

Dzięki, ale ja edytowane nieznacznie moje pytanie odpowiadać mojego kodu. Moim problemem jest rejestrowanie wyników, a nie tylko czekanie na ich zakończenie. Sądzę, że w tym przypadku nie ma innego wyboru, niż pętla z oczekiwaniem? – ctlaltdefeat

+0

@ctlaltdefeat No tak. Można jednak użyć LINQ do wyświetlenia przelicznika. Będę edytować, aby wyjaśnić. –

+0

Dzięki, ale nie całkiem rozumiem LINQ lub IEnumerable rzeczy w każdym razie: D Po prostu piszę rzeczy, które wyglądają tak, powinny być przeliczalne, i zwykle jest to – ctlaltdefeat

50

Szukasz Task.WhenAll:

var tasks = ObjectList 
    .Where(o => CalculateIfNeedToMakeTaskForO(o)) 
    .Select(o => OTaskAsync(o)) 
    .ToArray(); 
var results = await Task.WhenAll(tasks); 
var combinedResults = results.Select(r => "result for O is: " + r); 
+0

Hej, niektóre z twoich postów pomogły mi zacząć z asynchronizacją i czekam, ale okazuje się, że nie potrzebuję korzystać z ich funkcjonalności do tej pory! – ctlaltdefeat

+0

Podobne pytanie, jakie zadałem powyżej: sposób, w jaki to napisałeś, wydaje się, że nic się nie dzieje, dopóki nie dowiemy się, które obiekty w ObjectList potrzebują dla nich zadania, a które nie. Moim celem jest zadanie pierwszego obiektu (zakładając, że go potrzebuje), aby rozpocząć, gdy tylko obliczyliśmy, że potrzebujemy go, zanim obliczymy, czy drugi element tego potrzebuje. – ctlaltdefeat

+14

To jest lepsza odpowiedź, ponieważ asynchronicznie czeka na wynik. wywoływanie Task.WaitAll blokuje wątek wywołujący, dopóki wszystkie zadania nie zostaną zakończone –