1

我现在有一个应用程序,它是一个管道设计。在第一阶段,它将一些数据和文件读入 Stream。有一些中间阶段对数据流进行处理。然后是最后一个阶段,将流写到某个地方。这一切都是连续发生的,一个阶段完成,然后移交到下一个阶段。

这一切都很好,但现在数据量开始变得相当大(可能有数百 GB)。所以我认为我需要做一些事情来缓解这种情况。我最初的想法是我正在寻找一些反馈(作为一个独立的开发人员,我没有任何地方可以反弹这个想法)。

我正在考虑创建一个并行管道。从管道开始的对象将创建所有阶段并在其自己的线程中启动每个阶段。当第一阶段使流达到一定大小时,它将将该流传递到下一个阶段进行处理并启动自己的新流以继续填充。这里的想法是最后阶段将关闭流,因为第一阶段正在构建一个新流,因此我的内存使用量将保持较低。

所以问题:1)对这个设计的方向有什么高层次的想法吗?2)有没有一种更简单的方法,你能想到可能适用于这里?3)那里有什么东西可以做这样的事情我可以重复使用(不是我必须购买的产品)?

谢谢,

迈克D

4

3 回答 3

1

生产者/消费者模型是一个很好的方法。微软有他们新的并行扩展,它应该为你提供大部分的基础工作。查看Task对象。有一个可用于 .NET 3.5 / VS2008 的预览版。

您的第一个任务应该从流中读取数据块,然后将它们传递给其他任务。然后,在中间有尽可能多的任务在逻辑上合适。较小的任务(通常)更好。唯一需要注意的是确保最后一个任务按读取顺序保存数据(因为中间的所有任务可能以与它们开始时不同的顺序完成)。

于 2009-11-19T02:56:02.520 回答
0

对于您建议的设计,如果您还没有仔细阅读过生产者/消费者问题,您可能会想要了解一下。您需要很好地了解如何在这种情况下使用信号量。

您可以尝试的另一种方法是创建多个相同的管道,每个管道都在一个单独的线程中。这可能更容易编码,因为它的线程间通信要少得多。但是,根据您的数据,您可能无法以这种方式将其拆分为块。

于 2009-11-19T01:50:25.127 回答
0

在每个阶段,您是否读取整个数据块,进行操作,然后将整个卡盘发送到下一个阶段?

如果是这种情况,您正在使用“推送”技术,将整个数据块推送到下一阶段。您是否能够使用“拉”技术以更流畅的方式处理事情,例如庄园?每个阶段都是一个流,当您从该流中读取数据时,它会通过调用 read 从前一个流中提取数据。在读取每个流时,它会以小位从前一个流中读取,对其进行处理并返回处理后的数据。目标流决定了从前一个流中读取多少字节,并且您不必消耗大量内存。这就是 BizTalk 等应用程序的工作方式。有一些关于 BizTalk Pipeline 流如何工作的博客,我认为它可能正是您想要的。

这是一个多部分的博客条目,您可能会觉得有趣:

第 1
部分 第 2
部分 第 3
部分 第 4
部分 第 5 部分

于 2009-11-19T05:19:29.267 回答