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

    } 

} 
} 

Desire Out Помещенный

Это не зависит от работы Шаг1: Получение данных из XML Шаг2: сбросами данных 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

И ваш вопрос? –

+0

Мой вопрос в том, как я могу убедиться, что если шаг 2 приходит только после Step1, не до этого –

ответ

3

Для всех последовательных задач, которые вы должны только иметь один IContract. Метод выполнения этого контракта должен вызывать методы 2, 3 и т. Д., Которые все должны запускаться последовательно. Если у вас есть другая группа из 2 задач, которые будут выполняться последовательно, это будет еще один IContract. У вас не должно быть более одного IContract s, определенных для группы задач, которые должны выполняться последовательно. Если вы не хотите этого делать, вам нужно будет перепроектировать всю структуру, чтобы представить зависимости или что-то более активное.

0

Ваша основная проблема заключается в том, что вы не можете определить, используя отражение, что XMLJob и DumpToDBJob должны быть частью последовательности. Вы можете настроить это, используя пользовательские атрибуты.

Как отмечено 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

это нормально, если мне это нравится. Я всегда знаю, что только эти библиотеки должны выполняться последовательно. Я отредактировал вопрос и добавил подход в конце –

+1

@PavanJosyula уверен, если вы знаете, что эти две работы являются единственными специальными случаями, то вы можете их обработать специально. Обратите внимание, что вы можете тестировать типы для равенства; нет необходимости вызывать 'ToString()'; вы можете просто набрать 'IContract xj = list.Find (i => i.GetType() == typeof (XMLJob));' – phoog

Смежные вопросы