【问题标题】:Threading lists of tasks in .NET 4.NET 4 中的任务线程列表
【发布时间】:2011-05-24 03:28:52
【问题描述】:

我按照这些思路设置了一组结构良好的对象:

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();
  }
}

分成一系列任务。我以前使用过 Tasks,虽然我没有对它们做过任何真正复杂的事情,而且我只是不知道如何通过任意顺序调用序列来触发任意数量的任务。

除了启动它们并报告它们抛出的任何错误之外,我不需要以任何方式访问任务。最好是 DataSource2ProcessorA 中的错误不应阻止 DataSource2ProcessorB 运行,但如果编码更容易允许一个错误杀死整个 DataSource 的线程,我可以忍受。

【问题讨论】:

    标签: c# .net-4.0 task-parallel-library


    【解决方案1】:

    使用以下命令在单独的线程上触发每个处理事件并记录错误(或重新引发异常):

    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);
    

    【讨论】:

      【解决方案2】:

      您希望使用并行 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();
          }
      });
      

      也就是说,虽然这可以确保在 DataSource2ProcessorB 之前处理 DataSource2ProcessorA,但不能保证任务运行的顺序。

      【讨论】:

      • 我知道使用 Parallel 可能有某种方法可以做到这一点,但我正在考虑嵌套的 Parallels 和 ContinueWith 操作。我从来没有考虑过只在里面使用“老派”的 foreach 循环。 (我也不太确定如何传递列表。)谢谢!
      【解决方案3】:

      Multithreading improvements in .NET 4

      .net 4 添加了执行并行 foreach 的能力。

      【讨论】:

        【解决方案4】:

        为什么不使用 parallel.FX 库?您可以轻松使用parallel.ForParallel.ForEach 方法。 http://msdn.microsoft.com/en-us/magazine/cc163340.aspx

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-26
          • 1970-01-01
          • 2011-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多