-1

maxConcurrencyを10に設定すると、以下のコードでmaxパラレルタスクが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

[一度に1つの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();"というループが発生します。やはり効率的なパフォーマンスが必要です。 – Nitheesh

+0

はあなたが* maxConcurrency *にしたいものを何でも設定します。問題ない。 –

0

いいえいいえ、相互排他ブロックに入るための呼び出しがありません。

+0

Sunil、私はコードを変更して待機を含めるようにしましたか?その動作を確認するにはどうすればよいですか? – Nitheesh

+0

共有同時実行性> 10よりも多くのスレッドを作成し、約2秒以上タスクのスリープを誘発し、コンソール印刷を行います。 10プリントステートメントが表示され、遅れることを通知する –

関連する問題