2017-10-14 21 views
0

大きな計算タスクを実行する必要がある項目のリストがありますので、次のように実装しました。 私はここで何か悪いことをしているかどうか教えてください。C#で複数のタスクを処理/実装する方法

{ 
    "MainList": [{ 
      "Name": "First item from root task", 
      "Task": [{ 
       "SubTask1": "...", 
       "SubTask2": "..." 
      }] 
     }, 
     { 
      "Name": "Second item from root task", 
      "Task": [{ 
       "SubTask1": "...", 
       "SubTask2": "...", 
       "SubTask3": "...", 
       "SubTask4": "..." 
      }] 
     } 
    ] 
} 

シナリオ:

  1. リストから各項目には大きな計算タスクを実行する必要がT1を言います。
  2. いずれかのタスクの完了時には、同じリストの各アイテムに対して別のタスクを実行する必要があります(これはT1完了後に実行する必要があります)。 と並行して「タスク」 プロパティからすべてのサブタスクを実行する必要があります。

STEP 2のタスクは、最初のタスクが完了した後に実行しなければならず、これらのタスクは両方ともパラレルを実行できることに注意してください。シナリオ上の考慮

は、私は以下のようなコードを開発しました:

コード:

List<Task<object>> mainFirstTaskList = new List<Task<object>>(); 
List<Task<object>> mainSecondTaskList = new List<Task<object>>(); 
List<Task> subTaskList = new List<Task>(); 
foreach (var itm in MainList) 
{ 
    mainFirstTaskList.Add(Task.Factory.StartNew<object>(() => 
    { 
     //Use "itm" from iteration 
     //Perform big computational task on each item 
     return resultFirstMainList; 
    })); 
} 
while (mainFirstTaskList.Count > 0) 
{ 
    int finishedTask = Task.WaitAny(mainFirstTaskList.ToArray()); //waiting for any of the task to gets complete 
    Task<object> t = mainFirstTaskList[finishedTask]; 
    var result = t.Result; 

    //Perform Another Task on the same list 
    mainSecondTaskList.Add(Task.Factory.StartNew<object>(() => 
    { 
     //use result from first task completed 
     //Perform big computational task on each item 
     return resultSecondMainList; 
    })); 

    //Perform the task on sub item list 
    subTaskList.Add(Task.Factory.StartNew<object>(() => 
    { 
     //Have used Parallel.For to partition the sub task computation 
     //And have added this Parallel.For inside another Task, as Parallel.For will partition the tasks on current thread 
     Parallel.For(1, subItemIndex, i => 
     { 
      //Perform big task computation 
     }); 
    })); 
} 

を、私はここで間違っどんなことをしたした場合、私に知らせてください。

ありがとうございました!!!

答えて

0

私はあなたがしていることを大雑把に理解していると思います。このためにMicrosoftのReactive Frameworkを使用する必要があります。次に、これを行うことができます:

var query = 
    from mainItem in MainList.ToObservable() 
    from firstResult in Observable.Start(() => ProcessMainItem(mainItem)) 
    from secondResult in Observable.Start(() => ProcessFirstItem(firstResult)) 
    from subItem in secondResult.ToObservable() 
    from result in Observable.Start(() => ProcessSubItem(subItem)) 
    select result; 

IDisposable subscription = 
    query 
     .Subscribe(x => 
     { 
      /* Process results as they are computed */ 
     }); 

すべての計算は並行して実行され、結果は最終結果にまとめられます。

すべての中間結果を結合する場合は、select new { mainItem, firstResult, secondResult, subItem, result };を設定することもできます。

+0

ありがとう@Enigmativity、私はMicrosoftのReactiveにとって非常に新しく、「mainFirstTaskList」タスクを最初に開始し、タスクが完了すると1つずつ「mainSecondTaskList」と「subTaskList」を独立して開始する必要がありますそれぞれに。 "subTaskList"には複数のタスクがあるので、私はParallel.Forを使用しました。 あなたが書いたことは、すべてのタスクが並行して開始されますが、「mainSecondTaskList」と「subTaskList」の両方が「mainFirstTaskList」の結果に依存していることです。 私の実装に問題はありますか? –

+0

@GaneshChoudhari - 自分のコードが動作するかどうかをコメントするには、[mcve]を提供する必要があります。部分的なコードを完全に理解するのは難しいです。あなたは私のアプローチを試してみるべきです - あなたがマルチスレッドをどれくらいうまく処理しているのが驚くでしょう。 – Enigmativity

関連する問題