-1

如果我將maxConcurrency作爲10傳遞,下面的代碼將最大並行任務限制爲10?如何驗證一次運行的任務數量?在下面的代碼上下文中,SemaphoreSlim的用法是否正確?它會限制最大運行線程嗎?

public BlockingCollection<Task> _workTaskQueue; 

public void DequeueTask(int maxConcurrency) 
{ 
    var tasks = new List<Task>(); 
    using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency)) 
    { 
     foreach (var task in _workTaskQueue.GetConsumingEnumerable()) 
     { 
      concurrencySemaphore.Wait(); 
      if (!(task.IsCanceled) && task.Status == TaskStatus.Created) 
      { 
       task.ContinueWith((t) => { concurrencySemaphore.Release(); }); 
       tasks.Add(task); 
       task.Start(); 
      } 
     } 
    } 
    Task.WaitAll(tasks.ToArray()); 
} 
+1

參見https://stackoverflow.com/questions/14075029/have-a-set-of-tasks-with-only-x-running-at-a-time –

+0

非常感謝它幫助! – Nitheesh

+0

[有一組任務只能運行一次X](https://stackoverflow.com/questions/14075029/have-a-set-of-tasks-with-only-x-running-at -a-time) – Cheesebaron

回答

1

由於您利用my other answer改變了一點邏輯,我爲您準備了測試代碼。 (無需var tasks = new List<Task>();

Random rnd = new Random(); 
int maxConcurrency = 5; 
var _workTaskQueue = new System.Collections.Concurrent.BlockingCollection<Task>(); 
for (int i = 0; i < 250; i++) 
{ 
    //Tasks running 250=500ms 
    _workTaskQueue.Add(new Task(()=> { Task.Delay(250 + rnd.Next(250)).Wait(); })); 
} 
_workTaskQueue.CompleteAdding(); 
int runningTaks = 0; 

using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency)) 
{ 
    foreach (var task in _workTaskQueue.GetConsumingEnumerable()) 
    { 
     Console.WriteLine("LoopStart: " + runningTaks); 

     await concurrencySemaphore.WaitAsync(); 

     Console.WriteLine("GotASem : " + runningTaks); 

     task.Start(); 
     Interlocked.Increment(ref runningTaks); 
     task.ContinueWith(t => 
      { 
       Interlocked.Decrement(ref runningTaks); 
       concurrencySemaphore.Release(); 
      }); 

     if (runningTaks > maxConcurrency) throw new Exception("ERROR"); 
     Console.WriteLine("LoopEnd : " + runningTaks + Environment.NewLine); 
    } 

    Console.WriteLine("Finalizing: " + runningTaks); 
    //Make sure all all tasks have ended. 
    for (int i = 0; i < maxConcurrency; i++) 
    { 
     await concurrencySemaphore.WaitAsync(); 
    } 

    Console.WriteLine("Finished: " + runningTaks); 
} 
+0

謝謝L.B.太棒了。我有一個小問題:萬一如果我的maxConcurrency設置爲100將循環「await concurrencySemaphore.WaitAsync();」仍然有效的表現明智或我以前的task.waitall()更好? – Nitheesh

+0

設置你想要* maxConcurrency *。沒問題。 –

0

否。等待呼叫(進入互斥塊)缺失。

+0

Sunil,我修改了包含wait的代碼,它會工作嗎?我如何驗證其工作? – Nitheesh

+0

創建比共享併發更多的線程,> 10並在任務中誘發大約一秒或更長時間的睡眠並進行控制檯打印。 10打印報表將被看到併發布,他們將被推遲 –

相關問題