2012-02-26 12 views
5

używam Task Parallel Library, aby uruchomić pewne zadania, tak jak poniżej:- Wiedzieć, kiedy wszystkie zadania są zakończone

public static void Main() 
    { 
     for (var i = 0; i < 10; i++) 
     { 
      var x = i; 
      Task.Factory.StartNew(() => new WorkerClass(x).Do()); 
     } 

     // (*) Here I'd like to wait for all tasks to finish 
     Task.WaitAll(); 

     Console.WriteLine("Ready."); 
     Console.ReadLine(); 
    } 

Problem polega na tym, że niektóre zadania mogą same tworzyć nowe zadania. W ten sposób WorkerClass wygląda następująco:

public class WorkerClass 
{ 
    private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger(); 

    private readonly int _i; 

    public WorkerClass(int i) 
    { 
     _i = i; 
    } 

    public void Do() 
    { 
     if (_i % 3 == 0) 
      Task.Factory.StartNew(() => new WorkerClass(_i + 101).Do()); 

     Log.Info("Started {0}", _i); 
     Thread.Sleep(2000); 
     Log.Info("Done {0}", _i); 
    } 
} 

Dla każdej wartości i, która jest wielokrotnością 3, nowe zadanie jest uruchomiona.

Chciałbym móc poczekać, aż wszystkie zadania (w tym te utworzone przez inne zadania) zostaną zakończone.

Czy jest to czysty/wbudowany sposób, aby to zrobić (z lub bez OC)?

Odpowiedz

15

przechowywać odniesienie do wszystkich zadań najwyższego poziomu, a potem po prostu korzystać WaitAll:

var tasks = new Task[10]; 
    for (var i = 0; i < 10; i++) 
    { 
     var x = i; 
     tasks[i] = Task.Factory.StartNew(() => new WorkerClass(x).Do()); 
    } 

    Task.WaitAll(tasks); 

jak dla zadań podrzędnych, po prostu upewnij się dołączyć je do zadania nadrzędnego. Oznacza to, że zadanie nadrzędne nie przejdzie w stan kompletny, dopóki nie zostaną zakończone wszystkie zadania podrzędne.

Task.Factory.StartNew(() => { }, TaskCreationOptions.AttachedToParent); 
+1

Świetnie! Nie wiem, jak opuściłem opcję 'TaskCreationOptions.AttachedToParent' – GolfWolf

Powiązane problemy