是否有用于TPL数据流的DSL或声明系统?

时间:2014-03-27 02:57:32

标签: task-parallel-library tpl-dataflow

是否有任何DSL或其他完全或部分声明的机制来声明TPL数据流?或者是最好的(仅)练习,只需在代码中连接它们即可?

如果失败了,是否有使用任何数据流库的DSL或其他完全或部分声明性机制,我可以将其用作模型和/或创意来源?

(我搜索没有成功,所以也许一个不存在......或者我没有找到它。)

更新:在下面回答@svick我为什么要这个以及我从中获得了什么:

首先,我只是喜欢更稀疏的语法,更清楚地显示流程而不是细节。我想

downloadString => createWordList => filterWordList => findPalindromes;

优于

downloadString.LinkTo(createWordList);
createWordList.LinkTo(filterWordList);
filterWordList.LinkTo(findPalindromes);
findPalindromes.LinkTo(printPalindrome);

带有重复的名字和额外的标点符号。与您使用dot DSL描述DAG的方式类似,而不是对Visio DOM API的一系列调用。您可以想象网络流以及流水线的语法,特别是网络流量非常清晰。当然,这似乎并不引人注目,但我喜欢它。

其次,我认为使用DSL可以将DSL描述持久化,例如,作为数据库中一行中的字段,然后再实例化它。虽然这可能完全不同。

1 个答案:

答案 0 :(得分:1)

让我们从相关事实开始,然后从那里开始工作:

  1. TPL Dataflow还没有这样的东西。
  2. 没有一种将DSL嵌入C#的好方法。常见的编译器不可扩展,并且很难从基于字符串的DSL访问局部变量。
  3. C#中的运算符存在一些限制,但最重要的是运算符不能是通用的。这意味着稀疏语法要么不是类型安全的(这对我来说是不可接受的),要么它不能使用重载的运算符。
  4. IDisposableLinkTo()返回的可用于中断已创建链接的IDisposable通常不会被使用,因此不必支持它。 (或者设置流程的表达式可能会返回单个downloadString.Link(createWordList).Link(filterWordList).Link(findPalindromes); 来打破整个流程?)
  5. 因此,我认为可以做的最好的事情是:

    LinkTo()

    这可以避免重复public static class DataflowLinkExtensions { public static ISourceBlock<TTarget> Link<TSource, TTarget>( this ISourceBlock<TSource> source, IPropagatorBlock<TSource, TTarget> target) { source.LinkTo( target, new DataflowLinkOptions { PropagateCompletion = true }); return target; } public static void Link<TSource>( this ISourceBlock<TSource> source, ITargetBlock<TSource> target) { source.LinkTo( target, new DataflowLinkOptions { PropagateCompletion = true }); } } ,但效果不是很好。

    这种简单形式的实现大多是微不足道的:

    PropagateCompletion

    我选择将true设置为Link(),因为我觉得这里最有意义。但它也可以是Link()的选项。


    我认为Axum的大多数替代链接运算符与TPL Dataflow无关,但是可以通过将集合或数组作为new[] { source1, source2 }.Link(target); source.Link(target1, target2); 的参数之一来将多个块链接到同一块或从同一块链接。 :

    Link()

    如果source.Link(propagator1.Link(target1), target2); 实际返回了代表整个流程的内容(类似于Encapsulate()),您可以将其组合起来创建更复杂的流程,例如:

    {{1}}