Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 最优化的第三方物流数据流设计?_C#_Architecture_Asynchronous_Concurrency_Tpl Dataflow - Fatal编程技术网

C# 最优化的第三方物流数据流设计?

C# 最优化的第三方物流数据流设计?,c#,architecture,asynchronous,concurrency,tpl-dataflow,C#,Architecture,Asynchronous,Concurrency,Tpl Dataflow,我喜欢询问如何使用TPL数据流最佳地设计最优化的体系结构。我还没有编写代码,所以没有可以发布的示例代码。我也不是在寻找代码(除非自愿),但在设计方面的帮助将不胜感激: 要求如下: 我有3个核心数据块,它们以特定的方式相互依赖。Datablock1是生成Foo1类型对象的生产者。Datablock2应该订阅Foo1对象(来自Datablock1),并可能(不是在每个Foo1上,根据特定的函数)生成Foo2对象,该对象存储在输出队列中,供其他DataBlock使用。Datablock3还使用Foo1

我喜欢询问如何使用TPL数据流最佳地设计最优化的体系结构。我还没有编写代码,所以没有可以发布的示例代码。我也不是在寻找代码(除非自愿),但在设计方面的帮助将不胜感激:

要求如下:

我有3个核心数据块,它们以特定的方式相互依赖。Datablock1是生成Foo1类型对象的生产者。Datablock2应该订阅Foo1对象(来自Datablock1),并可能(不是在每个Foo1上,根据特定的函数)生成Foo2对象,该对象存储在输出队列中,供其他DataBlock使用。Datablock3还使用Foo1对象(来自Datablock1),并可能生成Datablock2使用并转换为Foo2对象的Foo3对象

总之,以下是数据块及其各自产生和消耗的内容:

  • 数据块1:产生(Foo1),消耗(无)
  • 数据块2:生产(Foo2),消费(Foo1,Foo3)
  • 数据块3:生产(Foo3),消费(Foo1)
另外一个要求是,在Datablock2和Datablock3中,相同的Foo1大约在同一时间被处理。如果Foo1对象首先被Datablock2使用,然后一旦Datablock2完成了它的工作,同样的Foo1对象就会被发布到Datablock3,以便它完成它的工作,这是可以的。Datablock2中的Foo2对象可以由对Foo1对象或Foo3对象的操作产生

我希望这是有道理的,如果还不清楚的话,我很乐意解释更多

我的第一个想法是为3个数据块中的每一个创建TPL数据流块,并使它们处理不同对象类型的传入流。另一个想法是分割数据块,让每个数据块只处理一种对象类型的流。你有什么建议,或者有没有更好的解决方案

Svick已经在Datablock1上提供了帮助,并且它已经可以运行了,我只是被困在如何将当前环境(如上所述)转换为TPL数据流的问题上


非常感谢任何想法或建议。

让我们把这个问题分成三部分,分别解决

第一个问题是如何有条件地生成项目。我认为最好的选择是使用并让函数返回一个包含一个或零个项的集合

另一个选项是,当您不想生成任何内容时,忽略
null
s并返回
null
。 但如果这样做,还必须将源链接到,以便
null
s不会停留在其输出缓冲区中

第二个问题是如何将foo1同时发送到block#2和block#3。我在这里可以看到两种方式:

  • 使用链接到两个目标块(#2和#3)的
    BroadcastBlock
    。注意这一点,因为
    BroadcastBlock
    没有输出队列,所以如果目标块延迟了一个项目,这意味着它不会处理它。因此,在这种情况下,不应设置块2和块3的
    BoundedCapacity
    。如果不这样做,它们将永远不会延迟,所有消息都将由两个块处理
  • 按块#2处理Foo1后,手动将其发送到块#3
  • 我不确定“大约同时”到底意味着什么,但一般来说,TPL数据流不能保证独立块的处理顺序。您可以使用更改不同块的优先级,但我不确定这在这里是否有用

    最后也是最复杂的问题是如何在单个块中处理不同类型的项。有几种方法可以做到这一点,但我不确定哪种方法最适合您:

  • 不要在单个块中处理它们。有一个
    TransformBlock
    和一个
    TransformBlock
    。然后,您可以将它们链接到一个
    缓冲块
  • 如您所建议的,使用
    BatchedJoinBlock
    ,将
    batchSize
    设置为1。这意味着生成的
    元组将始终包含一个
    Foo1
    或一个
    Foo3
  • 通过将
    BatchedJoinBlock
    链接到生成更合适类型的
    TransformBlock
    来增强先前的解决方案。这可以是
    Tuple
    (其中一个项将始终为
    null
    ),也可以是类似于F#的东西,它确保只设置两个项中的一个
  • 从头开始创建新的块类型,这正是您想要的。它应该是
    isoourceblock
    ,并且还具有两个属性:
    ITarget
    类型的
    Target1
    ITarget
    类型的
    Target2
    ,与内置连接块类似

  • 使用选项#1和#3,您还可以将块封装到单个自定义块中,从外部看,该块类似于#4中的块,因此更易于重用。

    让我们将此问题分成三部分,并分别解决

    第一个问题是如何有条件地生成项目。我认为最好的选择是使用并让函数返回一个包含一个或零个项的集合

    另一个选项是,当您不想生成任何内容时,忽略
    null
    s并返回
    null
    。 但如果这样做,还必须将源链接到,以便
    null
    s不会停留在其输出缓冲区中

    第二个问题是如何将foo1同时发送到block#2和block#3。我在这里可以看到两种方式:

  • 使用链接到两个目标块(#2和#3)的
    BroadcastBlock
    。注意这一点,因为
    BroadcastBlock
    没有输出队列,所以如果目标块延迟了一个项目,这意味着它不会处理它。因此,在这种情况下,不应设置块2和块3的
    BoundedCapacity
    。如果你不想