2012-12-12 4 views
10

Ich habe ein Objekt, das ein System.Threading.Tasks.Task zurückgibt:Wie starte ich eine Liste <Task> parallel?

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

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

An anderer Stelle ein List<MyClass> ich habe, so dass ich nach dem ein List<Task> zu erhalten:

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

Nun, da ich die List<Task> habe, wie kann Ich starte sie alle parallel? Gibt es eine prägnantere Möglichkeit, dies zu codieren?

Danke!

Antwort

19

Was meinst du mit "sie parallel starten"? Wenn Sie die Task laufen, führt sie auf einem anderen Thread, so meinen Sie wahrscheinlich einfach:

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

Aber wenn man so viele von ihnen haben, dass Sie die Ausgangslogik zu einem anderen Thread verschieben möchten, können Sie entweder nennen über Code in einem anderen Thread/Task (Ich verwende für kürzere Code).

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

Oder Sie können TPL Parallel.ForEach verwenden. Dies würde den ausführenden Thread immer noch blockieren, bis alle Tasks gestartet sind, aber es wird die Startaktion auf einem internen Threadpool ausführen, so dass es für eine große Anzahl von Elementen und einigen freien CPU-Kernen/Threads den Startvorgang erheblich beschleunigen könnte.

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

Danke, die 'Parallel.ForEach()' war was ich gesucht habe. – user833115xxx

+0

'Parallel.ForEach' blockiert den aktuellen Thread weiterhin, bis alle Iterationen abgeschlossen sind. – davenewza

+0

Sie haben Recht - die Frage war ziemlich unklar, aber auch meine Antwort. Wahrlich paralleler Weg ist es, (beliebige) 'task.Start()' Logik in einem separaten Thread auszuführen (d. H. Thread-Objekt, Task mit LongRunning-Erstellungsoption, Parallel.Invoke usw.) –

6

Ich könnte Ihre Frage missverstehen, aber ist es nicht nur Start bei jeder Aufgabe zu nennen?

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

Warten auf alle Aufgaben fertig zu:

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

Oder über Linq: myTaskList.ForEach (Aufgabe => task.Start()); –

+0

Ich konnte Parallel.Foreach nicht auf meiner Task ausführen, da es sich um eine Task im Promise-Stil handelte; Diese Task.WaitAll arbeitete stattdessen für mich. – user2494584