实现自定义的任务并行库(TPL)数据流Block

数据流Block(Dataflow Block)是.NET 4.5中新的高性能并行处理程序库的支撑核心。尽管其中提供了很多现成的功能,但有时候仍然需要自定义的block。Zlatko Michailov完成了一个文档,其中列出了定制的过程,还指出可能会遇到的诸多陷阱。完整的指南《实现自定义的任务并行库(TPL)数据流Block》可以在Parallel Programming with .NET中找到,我们这里会提供一些重点。

Zlatko提醒:在动手之前,你要先考虑是不是就是把现有的ITargetBlock和ISourceBlock放在一起。如果是的话,Encapsulate函数会给你创建一个新的IPropagatorBlock。该函数会完成大部分的样板代码,但是你仍然要显式声明如何把消息从目标传递到来源block。

要想有更多控制,你可以显式实现ITargetBlock和ISourceBlock。与大多数抽象接口不同,不是所有的方法都要在实现类的公共接口上暴露出去。有些方法,比如LinkTo和Complete是要被通用代码调用的,而其他像OfferMessage这样的方法,只能被其他block通过抽象接口调用。指南中的5.1节针对每个方法推荐了可见性规则。

接下来Zlatko展示了两个详细的例子。第一个是同步过滤block,第二个是同步变型block。尽管其中有很多样板代码,但的确演示了很多TPL数据流的内部运作机制。

Zlatko谈到异步block时,真正难以对付的代码出现了。你从一开始就要考虑锁层次这样的东西。Zlatko推荐内建block使用的方法,包括一个外发(outgoing)锁,一个进入(incoming)锁和一个值锁(value lock)。

标记一个block为完成,这看起来很简单,只要在调用Complete或Fault时设置Completion属性即可。可一旦开始使用异步block,即使是这样的操作也会很麻烦。比如,实际完成属性设置时,必须保证没有拥有某个锁,因此这可能出发其他的同步代码。

另一个考虑在于:是以贪婪还是非贪婪的方式消费消息。如果使用非贪婪block,那就得采用额外步骤,避免与监听同一个来源的其他目标冲突。

最后,Zlatko谈到了提供消息和链接目标。不过这就简单了,因为所有的操作本意都采取同步方式。

如果想了解更多信息,请查看DevLaps上的TPL数据流网站。

查看英文原文:Implementing Custom TPL Dataflow Blocks

你可能感兴趣的:(实现自定义的任务并行库(TPL)数据流Block)