TPL 数据流是不是适用于这种设计类型?

Posted

技术标签:

【中文标题】TPL 数据流是不是适用于这种设计类型?【英文标题】:Will TPL Dataflow work for this design type?TPL 数据流是否适用于这种设计类型? 【发布时间】:2013-03-29 12:07:39 【问题描述】:

我目前正在研究模拟连接对象之间的资源和消息传输的方法,例如设备的电源或网络系统上的控制消息:

CLICK FOR LARGER IMAGE.

我最近一直在研究 TPL 数据流,不是因为它的线程和并行性,而是它在不处理大量杂乱代码边缘情况的情况下实现数据流水线的能力如何。模拟可能每 500 毫秒左右只运行一次,而且时间要求并不严格。

我一直在玩这个库,并且已经阅读了文档并且现在已经阅读了几次,但我正在努力实现它的解决方案。在上图中的节点概念中,我不确定哪些适合 Dataflow 节点。

我很想就 TPL 数据流是否适合此处提供一些建议,如果适合,请提供数据流块对应项中每个图示节点的基本实现。

【问题讨论】:

所以大部分蓝色箭头都是网络传输? 时间在您的模拟中有多重要?因为数据流节点大多是独立的,通常不能保证时序。另外,功率单位是离散的吗?也就是说,一个节点可以请求0.5个单位吗? @usr 所有蓝色箭头都是“连接”。 @svick 更新了帖子:时间并不重要,因为模拟每 500 毫秒左右只滴答一次。节点可以请求与其充电速率相等范围内的整数单位功率,而充电速率可能会发生变化。 【参考方案1】:

我认为 TPL 数据流不太适合这一点。有几个原因:

    TDF 没有双工(双向)通信,您需要以某种方式将其固定。 在 TDF 中,块通常接收消息,然后生成更多消息以沿管道发送。这似乎不是您需要的(您的中心节点除外),至少在逻辑上不是这样。

但我认为您的要求不需要像 TDF 这样重量级的东西。我认为你应该做的是:

    创建一个简单的消息发送库,可能使用类似客户端-服务器的架构:客户端(例如消费者节点或分发节点)向服务器(例如分发节点或电源节点)发送消息,服务器回复,可能会有一些延迟。如果客户端连接到多个服务器,它会向所有服务器发送相同的消息并决定如何处理多个响应(可能只接受第一个响应;这也意味着客户端必须能够拒绝响应)。李> 创建一个PowerStore 类来存储能量并且可以用来获取能量。它将返回一个Task,因此消费者可以等到电源可用。 利用以上两点,搭建你的节点应该比较简单。

【讨论】:

【参考方案2】:

经过深思熟虑、原型设计和研究,我终于使用事件和委托实现了解决方案,并且效果很好!

唯一的主要设计问题是,在某些情况下,例如,如果 3 个分发节点连接成三角形,则消息将进入无限循环。或者如果一个节点连接到自身或两个节点多次相互连接。 我在事件监听器连接中用一些简单的逻辑覆盖了这些边缘案例:

public bool ConnectTo(Node peerNode)
        
            EthernetPort peerPort   = peerNode.GetFreePort();
            EthernetPort myPort     = this.GetFreePort();

            // Perform a check for free ports for both peers:
            if (peerPort == null || myPort == null)
                return false; // Either myself or my peer do not have a spare port.

            // Perform a check to make sure these nodes aren't already connected:
            if (this.HasConnectedNode(peerNode))
                return false;

            // Connect the two ports:
            myPort.Connect(peerNode, peerPort);
            peerPort.Connect(this, myPort);
            return true;
        
public bool HasConnectedNode(Node node) 
            foreach (var port in ethernetSwitch.ethernetPorts)
            
                if (port.peerNode == node)
                    return true; // Found a port already connected to this node.
            

            return false; // No port has this node connected to it.
        

最后,为了以防我遗漏了什么或者只是为了安全起见,我实现了一个带有 int timeToLive 变量的自定义 EventArgs 类型。每次节点处理消息时,此变量都会递减,如果达到 0,则丢弃该消息。

【讨论】:

以上是关于TPL 数据流是不是适用于这种设计类型?的主要内容,如果未能解决你的问题,请参考以下文章

TPL 数据流(TDF)和响应式扩展有啥区别?

TPL 和模拟

C# 适用于 Azure 表存储上的地理数据的类型

省略数据类型(例如“unsigned”而不是“unsigned int”)

Bottle.py 是不是适用于 html 关联数组?

TPL 数据流:在保持秩序的同时进行并行设计