последовательное выполнение внутри параллели для каждого цикла - PullRequest
0 голосов
/ 07 марта 2012

Мое требование - нечто подобное. У меня мало независимых работ и несколько последовательных работ, которые соответствуют контракту. В моем клиентском приложении внутри цикла 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 Put

Это независимая работа Шаг 1: Получение данных из XML Шаг 2: Дамп данных, которые пришли в 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());

Ответы [ 2 ]

3 голосов
/ 07 марта 2012

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

0 голосов
/ 07 марта 2012

Ваша основная проблема заключается в том, что вы не можете определить, используя рефлексию, что 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()). Но опять же, если вы используете отражение, вам потребуется какой-то способ определения правильных объектов для передачи конструктору этого задания и в каком порядке.

...