2012-12-12 15 views
10

Mam obiekt, który zwraca System.Threading.Tasks.Task:Jak równolegle uruchomić listę <Task>?

public class MyClass 
{ 
    public Task GetTask(object state, CancellationToken cancellationToken) 
    { 
     return new Task(Execute, state, cancellationToken); 
    } 

    public void Execute(object context) 
    { 
     //do stuff 
    } 
} 

indziej mam List<MyClass>, więc należy wykonać następujące czynności, aby uzyskać List<Task>:

var myTaskList = myClassList.Select(p => p.GetTask(null, cancellationToken)).ToList(); 

Teraz mam List<Task>, w jaki sposób Rozpoczynam je wszystkie równolegle? Czy istnieje bardziej zwięzły sposób kodowania tego?

Dzięki!

Odpowiedz

19

Co masz na myśli przez „zacząć je równolegle”? Po uruchomieniu Task, wykonuje w innym wątku, więc prawdopodobnie znaczy po prostu:

foreach(var task in myTaskList) 
{ 
    task.Start(); 
} 

Ale jeśli masz ich tak wiele, że chcesz przenieść logikę wychodząc do innego wątku, można nazwać powyżej kodu w innym wątku/zadaniu (używam krótszego kodu).

Task.Factory.StartNew(() => myTaskList.ForEach(task => task.Start())); 

Lub możesz użyć licencji TPL Parallel.ForEach. To nadal blokowałoby wykonywalny wątek, dopóki wszystkie zadania nie zostaną uruchomione, ale wykona akcję początkową w wewnętrznej puli wątków, więc w przypadku dużej liczby elementów i wolnych rdzeni procesora/wątków może znacznie przyspieszyć rozruch.

Parallel.ForEach(myTaskList, task => task.Start()); 
+1

Dziękuję, 'Parallel.ForEach()' było tym, czego szukałem. – user833115xxx

+0

'Parallel.ForEach' nadal będzie blokował bieżący wątek, dopóki nie zakończy wszystkich jego iteracji. – davenewza

+0

Masz rację - pytanie było dość niejasne, ale tak też jest z moją odpowiedzią. Prawdziwie równoległym sposobem jest wykonanie (dowolnej) logiki 'task.Start()' w osobnym wątku (tj. Obiekt Thread, zadanie z opcją tworzenia LongRunning, Parallel.Invoke itd.). –

6

Być może nie rozumiem twojego pytania, ale czy nie jest to po prostu wywoływanie polecenia Start przy każdym zadaniu?

foreach(Task task in myTaskList) 
{ 
    task.Start(); 
} 

Oczekiwanie na wszystkie zadania, aby zakończyć:

Task.WaitAll(myTaskList.ToArray()); 
+2

Lub przez Linq: myTaskList.ForEach (task => task.Start()); –

+0

Nie mogłem uruchomić Parallel.Foreach na moim zadaniu, ponieważ było to zadanie w stylu obietnicy; to Task.WaitAll pracował dla mnie zamiast tego. – user2494584

Powiązane problemy