2012-03-07 93 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 "); 

    } 

} 
} 

欲出把

这是独立工作 第一步:从XML 获取数据第二步:转储数据whihc排在XML 这是独立工作 按任意键继续。 。 。

我可以这样做

 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

而你的问题? – 2012-03-07 18:31:12

+0

我的问题是我如何确定如果步骤2只是在步骤1之后才到来,那么 – 2012-03-07 18:36:25

回答

3

对于所有的连续任务,你应该只有一个IContract。该合同的执行方法应该调用所有需要按顺序运行的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应该被立即执行。我已经编辑了这个问题,并在末尾添加了方法 – 2012-03-09 05:50:33

+1

@PavanJosyula当然,如果你知道这两个职位是唯一的特例,那么你可以特别对待他们。请注意,您可以测试类型是否相等;没有必要调用'ToString()';你可以输入'IContract xj = list.Find(i => i.GetType()== typeof(XMLJob));'' – phoog 2012-03-12 21:03:21