Потоки списков задач в .NET 4 - PullRequest
2 голосов
/ 23 мая 2011

У меня есть набор хорошо структурированных объектов, настроенных по следующим направлениям:

abstract class Data 
{
  public abstract void GetData();
  public abstract void Process();
}
abstract class DataSource1 : Data
{
  public void GetData() { ... }
}
class DataSource1ProcessorA : DataSource1
{
  public void Process() { ... }
}
abstract class DataSource2 : Data
{
  public void GetData() { ... }
}
class DataSource2ProcessorA : DataSource2
{
  public void Process() { ... }
}
class DataSource2ProcessorB : DataSource2
{
  public void Process() { ... }
}

В настоящее время я последовательно обрабатываю каждый DataSourceProcessor, который начинает увеличиваться по мере добавления новых источников и процессоров.Каждый источник совершенно не связан, но каждый процессор должен работать по порядку.Поэтому мне нужен способ превратить

new List<List<Data>> tasks = new List<List<Data>>()
{
  new List<Data>() { new DataSource1ProcessorA() },
  new List<Data>() { new DataSource2ProcessorA(), new DataSource2ProcessorB() }
}
foreach (List<Data> source in tasks)
{
  foreach(Data data in source)
  {
    data.GetData();
    data.Process();
  }
}

в серию задач.Я работал с Задачами раньше, хотя я не сделал ничего действительно сложного с ними, и я просто не могу понять, как выполнить произвольное количество задач с произвольной последовательностью последовательных вызовов.

Мне не нужно никоим образом получать доступ к Задачам, кроме как запускать их и сообщать о любых ошибках, которые они выдают.Предпочтительно ошибка в DataSource2ProcessorA не должна препятствовать выполнению DataSource2ProcessorB, но если при кодировании значительно проще разрешить одной ошибке уничтожить весь поток DataSource, я могу с этим смириться.

Ответы [ 4 ]

2 голосов
/ 23 мая 2011

Используйте ниже для запуска каждого события обработки в отдельном потоке и регистрации ошибок (или переброски исключений):

Task.Factory.StartNew(() => { data.GetData(); data.Process(); })
.ContinueWith(t => Logger.Error("An exception occurred while processing. Check the inner exception for details", t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
1 голос
/ 23 мая 2011

Вы хотите использовать параллельный foreach и действие, которое обрабатывает список для каждого элемента.То есть:

new List<List<Data>> tasks = new List<List<Data>>()
{
  new List<Data>() { new DataSource1ProcessorA() },
  new List<Data>() { new DataSource2ProcessorA(), new DataSource2ProcessorB() }
}

Parallel.ForEach(tasks, (items) =>
{
    foreach (var item in items)
    {
        item.GetData();
        item.Process();
    }
});

То есть, хотя это гарантирует, что DataSource2ProcessorA обрабатывается до DataSource2ProcessorB, нет никакой гарантии относительно порядка выполнения задач.

1 голос
/ 23 мая 2011

см. Улучшения многопоточности в .NET 4

.net 4 добавлена ​​возможность делать параллельный foreach.

0 голосов
/ 23 мая 2011

Почему вы не используете библиотеку parallel.FX?Вы можете легко использовать методы parallel.For или Parallel.ForEach.http://msdn.microsoft.com/en-us/magazine/cc163340.aspx

...