.NET 4 中任务列表的线程化

发布于 2024-11-09 06:25:33 字数 1220 浏览 0 评论 0原文

我按照以下方式设置了一组结构良好的对象:

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 的线程,我可以忍受这一点。

I have a set of nicely structured objects set up along these lines:

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() { ... }
}

Currently, I'm processing each DataSourceProcessor sequentially, which is starting to get long as we add more sources and processors. Each source is completely unrelated, but each processor needs to be run in order. So I need a way to turn

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

into a series of Tasks. I've worked with Tasks before, although I haven't done anything really complicated with them, and I just can't figure out how to fire off an arbitrary number of tasks with an arbitrary sequence of sequential calls.

I don't need to access the Tasks in any way, other than kicking them off and reporting any errors they throw. Preferably an error in DataSource2ProcessorA shouldn't prevent DataSource2ProcessorB from running, but if the coding is significantly easier to allow one error to kill the whole DataSource's thread, I can live with that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深居我梦 2024-11-16 06:25:33

使用下面的方法在单独的线程上触发每个处理事件并记录错误(或重新抛出异常):

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

Use below to fire off each processing event on a separate thread and log the errors (or re-throw exceptions):

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);
濫情▎り 2024-11-16 06:25:33

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

,尽管这确保了 DataSource2ProcessorADataSource2ProcessorB 之前得到处理,但无法保证任务的运行顺序。

You want to use a parallel foreach, and an action that processes the list in order for each item. That is:

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

That that, although this ensures that DataSource2ProcessorA is processed before DataSource2ProcessorB, there's no guarantee about the order in which tasks are run.

无名指的心愿 2024-11-16 06:25:33

请参阅 .NET 4 中的多线程改进

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

see Multithreading improvements in .NET 4

.net 4 added the ability to do parallel foreach.

烟织青萝梦 2024-11-16 06:25:33

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

Why don't you use parallel.FX library? you can use the parallel.For or Parallel.ForEach methods easily.
http://msdn.microsoft.com/en-us/magazine/cc163340.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文