2013-07-16 42 views
7

我有一些包含Action(System.Action)的ConcurrentQueue。 此隊列中的每個操作都需要運行(需要使用invoke調用)。如何限制通過並行任務庫運行的活動任務的數量?

當隊列不爲空=>動作需要調用=>但我想對運行的並行任務的數量做一些限制。除此之外,任何時候都可以將新操作添加到隊列中。

怎麼辦?

(使用.NET 4.0)

我寫的東西,但我不知道這是最好的辦法

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

你能解釋真正的問題嗎?爲什麼你覺得有必要限制任務的數量? –

+0

只是學術經驗..我想學習。但我也想知道爲什麼我不需要做這個限制? – Yanshof

+1

沒有必要限制任務的數量 - 我現在看到你正在談論*併發執行任務,而不是隊列中的總數; lazyberezovsky的答案如下,對於這種情況是正確的。 –

回答

14

上看看MSDN文章How to: Create a Task Scheduler That Limits Concurrency。你可以使用LimitedConcurrencyLevelTaskScheduler實現它來使你的代碼像這樣:

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

爲什麼這比解決方案更好OP建議使用SemaphoreSlim? – BornToCode

-1

你需要指定ParallelOptions

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

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

除了這裏沒有ForEach .... –

+0

這與任務無關... –