2012-03-07 18 views
0

私の要件はこのようなものです。私は独立した仕事はほとんどなく、契約に従う仕事はほとんどありません。私のクライアントアプリケーションでは、Parallel Forループ内で独立したタスクが順番どおりに実行されるようにする必要がありますが、シーケンシャルな場合は順番に実行する必要があります。以下は私のコードです。おかげで、各ループの並列実行で順次実行

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 
using System.Threading.Tasks; 

namespace Sample 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Program p = new Program(); 
     List<IContract> list = p.Run(); 

     Parallel.ForEach(list, t=> t.Execute()); 
    } 

    List<IContract> Run() 
    { 
     List<IContract> list = new List<IContract>(); 
    Type[] typesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes(); 
     Array.ForEach(
     typesInThisAssembly, 
     type => 
      { 
      // If the type of this interface is not IChartView, continue the loop 
      if (type.GetInterface(typeof(IContract).ToString()) != null) 
      { 
       var contractObj = Activator.CreateInstance(type, new object[] { }) as IContract; 
       list.Add(contractObj); 
      } 

      }); 

     return list; 
    } 
    } 


public interface IContract 
{ 
    void Execute(); 
} 

public class XMLJob : IContract 
{ 
    public void Execute() 
    { 
     Console.WriteLine("Step1: Getting data from XML"); 

    } 

} 
public class DumpToDBJob : IContract 
{ 
    public void Execute() 
    { 
     Console.WriteLine("Step2: Dumping Data whihc came in XML"); 

    } 

} 
public class IndependentJob1 : IContract 
{ 
    public void Execute() 
    { 
     Console.WriteLine("This is independent Job"); 

    } 

} 
public class IndependentJob2 : IContract 
{ 
    public void Execute() 
    { 
     Console.WriteLine("This is independent Job "); 

    } 

} 
} 

欲望はアウト

を置く。これは、独立した仕事 ステップ1です:XML からデータを取得するステップ2:データをダンプこれは独立した仕事 任意のキーを押して続行しにあるXML に来たwhihc。 。 。

私はあなただけの単一IContractを持っている必要があり、順次すべてのタスクについては、この

 Program p = new Program(); 
     List<IContract> list = p.Run(); 

     IContract xj = list.Find(i => i.GetType().ToString() == typeof(XMLJob).ToString()); 
     IContract dj = list.Find(i => i.GetType().ToString() == typeof(DumpToDBJob).ToString()); 
     list.Remove(xj); 
     list.Remove(dj); 

     Parallel.ForEach(list, l => l.Execute()); 
     List<Task> tasks = new List<Task>(); 

     Task t1 = Task.Factory.StartNew(xj.Execute); 
     Task t2 = t1.ContinueWith((antecedent)=>dj.Execute()); 

     tasks.Add(t1); 
     tasks.Add(t2); 
     Task.WaitAll(tasks.ToArray()); 
+4

質問がありますか? –

+0

私の質問は、Step2がステップ1の後に来るかどうかを確認する方法です。その前に、 –

答えて

3

のように行うことができます。その契約のexecuteメソッドは、すべてを順番に実行する必要がある2,3などのメソッドを呼び出す必要があります。あなたが2つのタスクの別のグループを持っている場合、それは別のIContractになるでしょう。順番に実行する必要があるタスクのグループに複数のIContractを定義してはいけません。そうしたくない場合は、フレームワーク全体を再設計して、依存関係などを導入する必要があります。

0

あなたの根本的な問題は、反射を使用して、XMLJobDumpToDBJobがシーケンスの一部であることを判断する方法がないことです。カスタム属性を使用して設定することができます。

Servyが指摘しているように、順次タスクの各セットについて、最初のものだけを並列リストに置き、シーケンス内の各タスクをその後続タスクから開始することができます。リフレクションを使用してロットを開始する場合、この方法では、DumpToDBJobの開始を避ける方法が必要です(最後の動作はXMLJobで開始されるためです)。

また、一連のタスクを順番に実行するラッパータスクを作成し、リストにというを入れることもできます。例えば

public class SequentialJob : IContract 
{ 
    private readonly IEnumerable<IContract> _children; 

    public SequentialJob(params IContract[] children) 
    { 
     _children = children; 
    } 

    public void Execute() 
    { 
     foreach (var child in children) 
      child.Execute(); 
    } 
} 

手動でこのクラスのインスタンスを作成していた場合、あなたはnew SequentialJob(new XMLJob(), new DumpToDBJob())を呼び出すことができます。しかし、あなたがリフレクションを使用している場合は、このジョブのコンストラクタに渡す正しいオブジェクトを特定する方法が必要です。

+0

がいいですか?私はいつもそれらのdllだけが連続して実行されるべきことを知っています。私は質問を編集し、最後に –

+1

@ PavanJosyulaというアプローチを追加しました。あなたがそれらの2つのジョブが唯一の特別なケースであることを知っていれば、それらを特別に扱うことができます。型の等しいかどうかをテストすることができます。 ToString()を呼び出す必要はありません。 'IContract xj = list.Find(i => i.GetType()== typeof(XMLJob));と入力するだけです。 – phoog