2013-07-16 9 views
7

Mam niektóre ConcurrentQueue, które zawierają Action (System.Action). Każda akcja w tej kolejce musi być uruchomiona (trzeba wywołać za pomocą polecenia invoke).Jak ograniczyć liczbę aktywnych zadań uruchomionych za pomocą równoległej biblioteki zadań?

Gdy kolejka nie jest pusta => akcja musi zostać wywołana => Ale chcę wprowadzić ograniczenie liczby zadań równoległych, które będą uruchamiane. Oprócz tego w każdej kolejce można dodać nową akcję.

Jak to zrobić?

(przy użyciu .NET 4.0)

napisałem coś, ale nie na pewno jest to najlepsze podejście

SemaphoreSlim maxThread = new SemaphoreSlim(5); 

while(!actionQueue.IsEmpty) 
     { 
      maxThread.Wait(); 
      Task.Factory.StartNew(() => 
      { 
       Action action; 
       if(actionExecution.TryDequeue(out action)) 
       { 
        action.Invoke(); 
       } 
      }, 
      TaskCreationOptions.LongRunning).ContinueWith((task) => maxThread.Release()); 
     } 
    } 
+2

Czy możesz wyjaśnić prawdziwy problem? Dlaczego czujesz potrzebę ograniczenia liczby zadań? –

+0

tylko akademickie doświadczenie .. chcę się uczyć. ale ja też chcę wiedzieć, dlaczego nie potrzebuję tego limitu? – Yanshof

+1

Nie ma potrzeby ograniczania liczby zadań - widzę, że teraz mówisz o * jednoczesnym wykonywaniu * zadań, a nie całkowitej liczby w kolejce; Odpowiedź Lazyberezovsky'ego poniżej jest poprawna dla tego scenariusza. –

Odpowiedz

14

spojrzeć na Artykuł MSDN How to: Create a Task Scheduler That Limits Concurrency. Możesz użyć z niego implementacji LimitedConcurrencyLevelTaskScheduler, aby utworzyć kod w następujący sposób:

var scheduler = new LimitedConcurrencyLevelTaskScheduler(5); 
TaskFactory factory = new TaskFactory(scheduler); 

while(!actionQueue.IsEmpty) 
{ 
    factory.StartNew(() => 
    { 
     Action action; 
     if(actionExecution.TryDequeue(out action))     
      action.Invoke(); 

    }, TaskCreationOptions.LongRunning); 
} 
+0

Dlaczego jest to lepsze niż rozwiązanie, które OP zaproponował użycie SemaphoreSlim? – BornToCode

-1

Musisz określić ParallelOptions

ParallelOptions options = new ParallelOptions(); 
options.MaxDegreeOfParallelism = 4;//value of your choice 

if (Parallel.ForEach(PDFFiles, options, element => 
{ 
    //do work 
} 
+1

Z wyjątkiem tutaj nie ma ForEach ... –

+0

Nie jest to związane z zadaniami ... –

Powiązane problemy