2016-12-06 45 views
4

私は、実行する必要があるタスク(〜1000)が非常に多いです。私は4コアプロセッサで動作しているので、同時に4つのタスクを並行して処理したいと思います。.NET待機タスク(async/await)

出発点として、ここにいくつかのサンプルコードを示します。

class Program 
{ 
    public class LongOperation 
    { 
     private static readonly Random RandomNumberGenerator = new Random(0); 
     const int UpdateFrequencyMilliseconds = 100; 

     public int CurrentProgress { get; set; } 

     public int TargetProcess { get; set; } 

     public LongOperation() 
     { 
      TargetProcess = RandomNumberGenerator.Next(
       (int)TimeSpan.FromSeconds(5).TotalMilliseconds/UpdateFrequencyMilliseconds, 
       (int)TimeSpan.FromSeconds(10).TotalMilliseconds/UpdateFrequencyMilliseconds); 
     } 

     public async Task Execute() 
     { 
      while (!IsCompleted) 
      { 
       await Task.Delay(UpdateFrequencyMilliseconds); 
       CurrentProgress++; 
      } 
     } 

     public bool IsCompleted => CurrentProgress >= TargetProcess; 
    } 

    static void Main(string[] args) 
    { 
     Task.Factory.StartNew(async() => 
     { 
      var operations = new List<LongOperation>(); 

      for(var x = 1; x <= 10; x++) 
       operations.Add(new LongOperation()); 

      await ProcessOperations(4, operations); 
     }).Wait(); 
    } 

    public static async Task ProcessOperations(int maxSimultaneous, List<LongOperation> operations) 
    { 
     await Task.WhenAll(operations.Select(x => x.Execute())); 
     // TODO: Process up to 4 operations at a time, until every operation is completed. 
    } 
} 
私は、単一のawait可能な中で、私が使用して、すべての操作が完了するまで、私は、一度に4つの操作まで処理する ProcessOperationsを構築したいどのようにどのようなクラスのいくつかの入力を希望

Task

私はSemaphoreSlimオブジェクトを何らかの方法で使用することを考えています。なぜなら、リソース/プロセスを絞り込むように見えるからです。

+7

[TPL DataFlow](https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx)を参照する必要があります。これは、Microsoftが正確に提供するライブラリですあなたがしようとしている状況。 'List 'を 'ActionBlock 'に置き換え、並列制限を設定するだけでよいでしょう。 –

+0

私は車輪を発明しようとしていたことを知っていましたが、どこでそれを見つけるか分からなかっただけです。ありがとう! –

答えて

3

は、すでに述べたように、あなたが二つのブロックと、処理の前にメッセージを格納するため、およびそれらの上に実際のアクションのために、便利なTPL Dataflow libraryを使用する必要があり、提案されて:

// storage 
var operations = new BufferBlock<LongOperation>(); 
// no more than 4 actions at the time 
var actions = new ActionBlock<LongOperation>(x => x.Execute(), 
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 }); 

// consume new operations automatically 
operations.LinkTo(actions); 
for(var x = 1; x <= 10; ++x) 
{ 
    // blocking sending 
    operations.Post(new LongOperation()); 
    // awaitable send for async operations 
    // await operations.SendAsync(new LongOperation()); 
} 

また、あなたは、いくつかのスロットル制限をintriduceことができ、あなたのバッファのためのオプションをBoundedCapacityに設定することで、その時点で30個以下の操作を行うようにします。

関連する問題