2016-09-16 8 views
0

Mit zwei Aufgaben, die On/Off ausführen, möchte ich eine Liste dieser (Paare) erstellen und sie parallel ausführen. Bedeutung: jeder Task kapselt TaskA und TaskB - und TaskB wartet immer auf TaskA zuerst zu beenden. Also soll ich mit paralleler Ausführung von "set" am Ende von TaskA/TaskBAusführen von Aufgabenpaaren parallel

Aufgabe = {TaskA, TaskB}, {TaskA, TaskB}, {TaskA, TaskB} : diese 3 Sätze von Aufgaben auszuführen, die in parallel

private static async Task TaskA() 
    { 
     await Task.Delay(2000); 
     Console.WriteLine("ended TaskA"); 
    } 

    private static async Task TaskB() 
    { 
     await Task.Delay(2000); 
     Console.WriteLine("ended TaskB"); 
    } 

    static void StartTask() 
    { 
     Task.Run(() => 
     { 
      TaskA().Wait(); 
      TaskB().Wait(); 
     }); 
    } 

Main:

 List<Task> tasks = new List<Task>(); 
     int taskCount = 3; 

     for (var i = 0; i < taskCount; i++) 
     { 
      var task = new Task(StartTask); 
      tasks.Add(task); 
     } 

     Parallel.ForEach(tasks, task => task.Start()); 

Derzeit bin immer ich dieses:

ended TaskA 
ended TaskA 
ended TaskA 
ended TaskB 
ended TaskB 
ended TaskB 

Ich glaube, die ausgegeben werden soll:

ended TaskA 
ended TaskB 
ended TaskA 
ended TaskB 
// etc.. 

Auch dies versucht, aber immer noch dasselbe Problem:

static void StartTask() 
{ 
    Task task = TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion); 
} 

Edit 1:

Parallel.For(1, taskCount, (i, state) => 
    { 
     TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion); 
    }); 
+0

Warum nicht einfach TaskB vom Ende des taska laufen? –

+0

Ich tue das, was ich tat – BobSwanson

+0

private statische asynchrone Task TaskA() { erwarten Task.Delay (2000); Console.WriteLine ("beendete TaskA"); TaskB(); } –

Antwort

2

I glaube, die Ausgabe sollte sein: ...

Nein, das ist nicht was "parallel" bedeutet. Wenn Sie drei Paare starten, würde ich die Ausgabe erwarten, die Sie bereits sehen.

Das heißt, es gibt ein paar Dinge im Code, die keinen Sinn ergeben. Zunächst einmal zwischen "parallel" (mehrere Threads) und "gleichzeitig" unterscheiden (mehrere Dinge gleichzeitig tun). Es sieht aus wie Ihre Aufgaben natürlich asynchron sind, also lassen Sie uns die Dinge neu zu schreiben asynchrone Programmierung statt Einfädeln mit:

  • ersetzen Wait mit await.
  • Befreien Sie sich von Task.Run.

Es ist einfacher, nur TaskA und TaskB in eine neue „-Paar Aufgabe“ zu komponieren:

static async Task PairTaskAsync() 
{ 
    await TaskA(); 
    await TaskB(); 
} 

Jetzt wollen Sie nur 3 dieser „-Paar Aufgaben“ gleichzeitig ausgeführt werden. Der alte Code verwendet den Task-Konstruktor und dann parallelisiert beginnend die Aufgaben - was ziemlich komplett falsch ist, auch wenn wir wollen, Parallelität zu tun. Was wir nicht tun; Wir wollen asynchrone Parallelität.

Asynchronous Gleichzeitigkeit ist in der Regel mit Task.WhenAll erreicht:

List<Task> tasks = new List<Task>(); 
int taskCount = 3; 

for (var i = 0; i < taskCount; i++) 
    tasks.Add(PairTaskAsync()); 

await Task.WhenAll(tasks); 

oder für maximale Prägnanz:

await Task.WhenAll(Enumerable.Range(0, 3).Select(_ => PairTaskAsync())); 
+0

Stephen, können Sie bitte Kommentare zu Ihrem Code hinzufügen, um es klarer zu machen ?. Wenn PairTaskAsync startet? wenn du hinzufügst? oder bei Wartezeile? – BobSwanson

+0

Wo kann ich auch eine Stoppuhr platzieren? zu wissen, wie lange TaskA und TaskB in einem einzelnen Paar dauerte, um zu beenden? – BobSwanson

+0

Gibt es ein Buch, das Async/Parallelität/Parallelität in leicht verständlicher, prägnanter Weise erklären würde? – BobSwanson

Verwandte Themen