我想将需要按顺序处理的多个流中的相关任务(在每个流中)排队。这些流可以并行处理。
具体来说,假设我需要两个队列,并且我希望每个队列中的任务按顺序处理。以下是示例伪代码,用于说明所需的行为:
Queue1_WorkItem wi1a=...;
enqueue wi1a;
... time passes ...
Queue1_WorkItem wi1b=...;
enqueue wi1b; // This must be processed after processing of item wi1a is complete
... time passes ...
Queue2_WorkItem wi2a=...;
enqueue wi2a; // This can be processed concurrently with the wi1a/wi1b
... time passes ...
Queue1_WorkItem wi1c=...;
enqueue wi1c; // This must be processed after processing of item wi1b is complete
下面是一个带有箭头的图表,说明了工作项之间的依赖关系:
问题是如何使用 C# 4.0/.NET 4.0 执行此操作?现在我有两个工作线程,每个队列一个,我使用BlockingCollection<>
对于每个队列。我想转而利用 .NET 线程池,让工作线程同时(跨流)处理项目,但在流内串行处理。换句话说,我希望能够表明,例如 wi1b 取决于 wi1a 的完成,而不必在 wi1b 到达时跟踪完成情况并记住 wi1a。换句话说,我只想说,“我想为queue1提交一个工作项,该工作项将与我已经为queue1提交的其他项目串行处理,但可能与提交到其他队列的工作项并行处理”。
我希望这个描述是有道理的。如果没有,请随时在评论中提出问题,我将相应地更新此问题。
谢谢阅读。
Update:
总结到目前为止的“有缺陷”的解决方案,以下是答案部分中我无法使用的解决方案以及我无法使用它们的原因:
TPL 任务需要指定先行任务ContinueWith()
。我不想在提交新任务时保留每个队列的先行任务的知识。
TDF ActionBlocks 看起来很有前途,但发布到 ActionBlock 的项目似乎是并行处理的。我需要串行处理特定队列的项目。
更新2:
RE: 动作块
看来,设置MaxDegreeOfParallelism
选项之一可防止并行处理提交给单个任务的工作项ActionBlock
。因此,似乎有一个ActionBlock
每个队列解决了我的问题,唯一的缺点是这需要安装和部署 Microsoft 的 TDF 库,而我希望有一个纯粹的 .NET 4.0 解决方案。到目前为止,这是候选人接受的答案,除非有人能够找到一种方法,使用纯 .NET 4.0 解决方案来实现此目的,并且不会退化为每个队列一个工作线程(我已经在使用)。