2017-08-26 10 views
1

私は、非同期メソッドの反復を実行する最善の方法を考え出しています。 基本的には、最初のタイムパンではTimeSpanDictionary<Item,TimeSpan>が実行されます。例えば(ネストされた反復を使用して)非同期メソッド反復を無限に実行する

var iteration = new TimeSpan().FromSeconds(60); 

var items = new Dictionary<Item,TimeSpan>(); 
items.Add(item1,new TimeSpan().FromSeconds(10)) 
items.Add(item2,new TimeSpan().FromSeconds(30)) 

それ仮定しても安全である:フィット常に、秒に変換するときに、辞書の項目の

  • TimeSpanは、常に<iteration
  • iterationより NTimeSpan(辞書のアイテムの繰り返し回数がアイテムのタイムスパンより60秒の場合1または2または3または6または10または15などのいずれかである。 私は辞書で TimeSpanで定義されている(非同期メソッドごと Xミリを実行する必要があります例えば、各 Itemに対して

:。例の2つの項目のことを意味

public async Task<int> MyMethod(Item item) 
{ 
    return await 3; // In reality something is done and a result is returned 
} 

と60秒のタイムスパン、私はT00:00で開始した場合、私はT00:00時およびで(item1 6回(T00:00T00:10T00:20などで)ためとitem2 2回MyMethodを実行する必要があります)。

この部分は比較的単純ですが、ちょっと苦労しているのは、iterationを60秒後にもう一度繰り返して、前の手順が完了したかどうかを確認することです。例えば、item1ためMyMethodが、私はまだある時点で私はアクティブitem1ためMyMethodの複数の実行を持っていることを意味している60秒(後に別の反復を開始したい完了するまでに12秒かかります。


私がやろうとした

何かがContinueWith(() => { MyMethod(item)MyMethodへの再帰呼び出しvoidですが、それは仕事を得ることができませんでした。

+0

タイマでRxを試しましたか? – VMAtm

答えて

1

私は実際に問題を自分で解決してきました。 Iterationを反復を表すクラスであります:

public void RunIterations() 
{ 
    var iterations = new List<Iteration>(); 

    // Adding items that represent the iterations to run 

    // Here we're creating an array of tasks for each iteration 
    // The running RunIteration for each iteration that needs to be created 
    // However, the tasks will never finish unless the cancellation is requested (as we can see in RunIteration method). 
    var iterationTasks = new Task[iterations.Count]; 

    var iterationIndex = 0; 
    foreach (Iteration iteration in iterations) 
    { 
     iterationTasks[iterationIndex] = RunIteration(iteration); 
     iterationIndex++; 
    } 

    Task.WaitAll(iterationTasks); 
} 

private async Task RunIteration(Iteration iteration) 
{ 
     // We're creating an endless loop that will keep starting the RunAsync() for the iteration until the cancellation is requested. 
     while (!_cancellationTokenSource.IsCancellationRequested) 
     { 
      // We're running the RunAsync() without waiting for it to finish. 
      // It's done on purpose: in case any stages in the iteration take more time than expected 
      // then another iteration is started in parallel as the previous one is finishing. 
      iteration.RunAsync().ContinueWith(
       task => { 
        DoSomethingWithResult(task.Result); 
       }); 

      // Waiting for the duration of the iteration to start the next one. 
      await Task.Delay((new TimeSpan().FromSeconds(60)); 
     } 
} 
関連する問題