2009-11-19 92 views
1

我现在有一个应用程序,这是一个管道设计。在第一阶段中,它将一些数据和文件读入Stream。有一些中间阶段可以处理数据流。然后有一个最后阶段将流写入某处。这一切都是连续发生的,一个阶段完成,然后转入下一个阶段。C#流设计问题

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

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

所以问题: 1)对这个设计的方向有什么高层次的想法? 2)是否有一种更简单的方法,您可以认为这可能适用于此? 3)有没有什么东西可以重复使用(不是我必须购买的产品)?

感谢,

拾音

回答

1

生产者/消费者模式是一种很好的处理方式。而且微软有新的Parallel Extensions这应该为你提供大部分的基础工作。看看Task对象。有一个预览版可用于.NET 3.5/VS2008。

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

+0

的并行扩展看起来非常有前途。我想我可以为每个阶段创建一个任务,开始每个阶段,并使用新的Concurrent Collection类在阶段之间传递流。我真的不想使用VS 2010,我似乎无法再找到预览版。我会继续寻找。 – MikeD 2009-11-19 06:36:46

+0

预览的下载链接如下,但MS似乎已经改变了他们的网站,链接不再工作:-( http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD -593D-4B3C-B055-694C50D2B0F3 – ligos 2009-11-22 06:19:28

0

对于你提出的设计,你会希望有producer/consumer problems阅读,如果你还没有一个好的。在这种情况下,你需要很好地理解如何使用信号量。

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

0

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

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

这里有一个多部分博客文章,你可能会感兴趣:

Part 1
Part 2
Part 3
Part 4
Part 5

+0

呃,为什么downvote?这个答案有什么问题? – Jeremy 2009-12-21 22:08:43